@@ -145,36 +145,44 @@ object Long {
145
145
146
146
// Must be called only with valid radix
147
147
private def toStringImpl (i : scala.Long , radix : Int ): String = {
148
+ import js .JSNumberOps .enableJSNumberOps
149
+
148
150
val lo = i.toInt
149
151
val hi = (i >>> 32 ).toInt
150
152
151
153
if (lo >> 31 == hi) {
152
154
// It's a signed int32
153
- import js .JSNumberOps .enableJSNumberOps
154
155
lo.toString(radix)
155
- } else if (hi < 0 ) {
156
- val neg = - i
157
- " - " + toUnsignedStringInternalLarge(neg.toInt, (neg >>> 32 ).toInt, radix)
156
+ } else if ((( hi ^ (hi >> 10 )) & 0xffe00000 ) == 0 ) { // see RuntimeLong.isSignedSafeDouble
157
+ // (lo, hi) is small enough to be a Double, so toDouble is exact
158
+ i.toDouble.toString( radix)
158
159
} else {
159
- toUnsignedStringInternalLarge(lo, hi, radix)
160
+ val abs = Math .abs(i)
161
+ val s = toUnsignedStringInternalLarge(abs.toInt, (abs >>> 32 ).toInt, radix)
162
+ if (hi < 0 ) " -" + s else s
160
163
}
161
164
}
162
165
163
166
// Must be called only with valid radix
164
167
private def toUnsignedStringImpl (i : scala.Long , radix : Int ): String = {
168
+ import js .JSNumberOps .enableJSNumberOps
169
+
165
170
val lo = i.toInt
166
171
val hi = (i >>> 32 ).toInt
167
172
168
173
if (hi == 0 ) {
169
174
// It's an unsigned int32
170
- import js .JSNumberOps .enableJSNumberOps
171
175
Integer .toUnsignedDouble(lo).toString(radix)
176
+ } else if ((hi & 0xffe00000 ) == 0 ) { // see RuntimeLong.isUnsignedSafeDouble
177
+ // (lo, hi) is small enough to be a Double, so toDouble is exact
178
+ i.toDouble.toString(radix)
172
179
} else {
173
180
toUnsignedStringInternalLarge(lo, hi, radix)
174
181
}
175
182
}
176
183
177
- // Must be called only with valid radix and with (lo, hi) >= 2^30
184
+ // Must be called only with valid radix and with (lo, hi) >= 2^53
185
+ @ inline // inlined twice: once in toStringImpl and once in toUnsignedStringImpl
178
186
private def toUnsignedStringInternalLarge (lo : Int , hi : Int , radix : Int ): String = {
179
187
import js .JSNumberOps .enableJSNumberOps
180
188
import js .JSStringOps .enableJSStringOps
@@ -188,38 +196,33 @@ object Long {
188
196
val approxNum =
189
197
Integer .toUnsignedDouble(hi) * TwoPow32 + Integer .toUnsignedDouble(lo)
190
198
191
- if ((hi & 0xffe00000 ) == 0 ) { // see RuntimeLong.isUnsignedSafeDouble
192
- // (lo, hi) is small enough to be a Double, so approxNum is exact
193
- approxNum.toString(radix)
194
- } else {
195
- /* See RuntimeLong.toUnsignedString for a proof. Although that proof is
196
- * done in terms of a fixed divisor of 10^9, it generalizes to any
197
- * divisor that statisfies 2^12 < divisor <= 2^30 and
198
- * ULong.MaxValue / divisor < 2^53, which is true for `radixPowLength`.
199
- */
200
-
201
- val radixInfo = StringRadixInfos (radix)
202
- val divisor = radixInfo.radixPowLength
203
- val divisorInv = radixInfo.radixPowLengthInverse
204
- val paddingZeros = radixInfo.paddingZeros
205
-
206
- // initial approximation of the quotient and remainder
207
- var approxQuot = Math .floor(approxNum * divisorInv)
208
- var approxRem = lo - divisor * unsignedSafeDoubleLo(approxQuot)
209
-
210
- // correct the approximations
211
- if (approxRem < 0 ) {
212
- approxQuot -= 1.0
213
- approxRem += divisor
214
- } else if (approxRem >= divisor) {
215
- approxQuot += 1.0
216
- approxRem -= divisor
217
- }
218
-
219
- // build the result string
220
- val remStr = approxRem.toString(radix)
221
- approxQuot.toString(radix) + paddingZeros.jsSubstring(remStr.length) + remStr
199
+ /* See RuntimeLong.toUnsignedString for a proof. Although that proof is
200
+ * done in terms of a fixed divisor of 10^9, it generalizes to any
201
+ * divisor that statisfies 2^12 < divisor <= 2^30 and
202
+ * ULong.MaxValue / divisor < 2^53, which is true for `radixPowLength`.
203
+ */
204
+
205
+ val radixInfo = StringRadixInfos (radix)
206
+ val divisor = radixInfo.radixPowLength
207
+ val divisorInv = radixInfo.radixPowLengthInverse
208
+ val paddingZeros = radixInfo.paddingZeros
209
+
210
+ // initial approximation of the quotient and remainder
211
+ var approxQuot = Math .floor(approxNum * divisorInv)
212
+ var approxRem = lo - divisor * unsignedSafeDoubleLo(approxQuot)
213
+
214
+ // correct the approximations
215
+ if (approxRem < 0 ) {
216
+ approxQuot -= 1.0
217
+ approxRem += divisor
218
+ } else if (approxRem >= divisor) {
219
+ approxQuot += 1.0
220
+ approxRem -= divisor
222
221
}
222
+
223
+ // build the result string
224
+ val remStr = approxRem.toString(radix)
225
+ approxQuot.toString(radix) + paddingZeros.jsSubstring(remStr.length) + remStr
223
226
}
224
227
225
228
def parseLong (s : String , radix : Int ): scala.Long = {
0 commit comments