@@ -9,6 +9,7 @@ import java.util.UUID
99import com .github .plokhotnyuk .jsoniter_scala .core .JsonWriter ._
1010import scala .annotation .tailrec
1111import scala .{specialized => sp }
12+ import java .lang .Long .compareUnsigned
1213
1314/**
1415 * A writer for iterative serialization of JSON keys and values.
@@ -2269,8 +2270,8 @@ final class JsonWriter private[jsoniter_scala](
22692270 val pow10 = floatPow10s(31 - e10)
22702271 val hi64 = unsignedMultiplyHigh1(pow10, m2.toLong << (h + 37 )) // TODO: when dropping JDK 17 support replace by Math.unsignedMultiplyHigh(pow10, m2.toLong << (h + 37))
22712272 m10 = (hi64 >>> 36 ).toInt * 10
2272- val dotOne = hi64 & 0xFFFFFFFFFL
22732273 val halfUlpPlusEven = (pow10 >>> (28 - h)) + ((m2IEEE + 1 ) & 1 )
2274+ val dotOne = hi64 & 0xFFFFFFFFFL
22742275 var m10Corr =
22752276 if ({
22762277 if (m2IEEE == 0 ) halfUlpPlusEven >>> 1
@@ -2374,33 +2375,17 @@ final class JsonWriter private[jsoniter_scala](
23742375 val lo64_2 = pow10_1 * cb
23752376 var hi64 = unsignedMultiplyHigh2(pow10_1, cb) // TODO: when dropping JDK 17 support replace by Math.unsignedMultiplyHigh(pow10_1, cb)
23762377 val lo64 = lo64_1 + lo64_2
2377- hi64 += java.lang.Long .compareUnsigned(lo64, lo64_1) >>> 31
2378+ hi64 += compareUnsigned(lo64, lo64_1) >>> 31
2379+ m10 = (hi64 >>> 6 ) * 10L
2380+ val halfUlpPlusEven = (pow10_1 >>> - h) + ((m2.toInt + 1 ) & 1 )
23782381 val dotOne = (hi64 << 58 ) | (lo64 >>> 6 )
2379- val halfUlp = pow10_1 >>> - h
2380- val even = (m2.toInt + 1 ) & 1
2381- if (java.lang.Long .compareUnsigned(halfUlp + even, - 1 - dotOne) > 0 ) {
2382- m10 = (hi64 >>> 6 ) * 10L + 10L
2383- } else if (m2IEEE != 0 ) {
2384- if (java.lang.Long .compareUnsigned(halfUlp + even, dotOne) > 0 ) {
2385- m10 = (hi64 >>> 6 ) * 10L
2386- } else {
2387- m10 = (hi64 * 10L + unsignedMultiplyHigh2(lo64, 10L ) + { // TODO: when dropping JDK 17 support replace by Math.unsignedMultiplyHigh(lo64, 10L)
2388- if (dotOne == 0x4000000000000000L) 0x1FL
2389- else 0x20L
2390- }) >>> 6
2391- }
2382+ if (compareUnsigned(halfUlpPlusEven, - 1 - dotOne) > 0 ) m10 += 10L
2383+ else if (m2IEEE != 0 ) {
2384+ if (compareUnsigned(halfUlpPlusEven, dotOne) <= 0 ) m10 = calculateM10(hi64, lo64, dotOne)
23922385 } else {
23932386 val tmp = (dotOne >>> 4 ) * 10L
2394- if (java.lang.Long .compareUnsigned((tmp << 4 ) >>> 4 , (halfUlp >>> 4 ) * 5L ) > 0 ) {
2395- m10 = (hi64 >>> 6 ) * 10L + ((tmp >>> 60 ).toInt + 1 )
2396- } else if (java.lang.Long .compareUnsigned(halfUlp >>> 1 , dotOne) > 0 ) {
2397- m10 = (hi64 >>> 6 ) * 10L
2398- } else {
2399- m10 = (hi64 * 10L + unsignedMultiplyHigh2(lo64, 10L ) + { // TODO: when dropping JDK 17 support replace by Math.unsignedMultiplyHigh(lo64, 10L)
2400- if (dotOne == 0x4000000000000000L) 0x1FL
2401- else 0x20L
2402- }) >>> 6
2403- }
2387+ if (compareUnsigned((tmp << 4 ) >>> 4 , (halfUlpPlusEven >>> 4 ) * 5L ) > 0 ) m10 += (tmp >>> 60 ).toInt + 1
2388+ else if (compareUnsigned(halfUlpPlusEven >>> 1 , dotOne) <= 0 ) m10 = calculateM10(hi64, lo64, dotOne)
24042389 }
24052390 }
24062391 val len = digitCount(m10)
@@ -2452,6 +2437,12 @@ final class JsonWriter private[jsoniter_scala](
24522437 count = pos
24532438 }
24542439
2440+ private [this ] def calculateM10 (hi : Long , lo : Long , dotOne : Long ): Long =
2441+ (hi * 10L + unsignedMultiplyHigh2(lo, 10L ) + { // TODO: when dropping JDK 17 support replace by Math.unsignedMultiplyHigh(lo64, 10L)
2442+ if (dotOne == 0x4000000000000000L) 0x1FL
2443+ else 0x20L
2444+ }) >>> 6
2445+
24552446 private [this ] def unsignedMultiplyHigh2 (x : Long , y : Long ): Long =
24562447 Math .multiplyHigh(x, y) + (y & (x >> 63 )) // Use implementation that works only when y is positive
24572448
0 commit comments