diff --git a/jsoniter-scala-core/jvm/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala b/jsoniter-scala-core/jvm/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala index ca447845d..52e4bd2a9 100644 --- a/jsoniter-scala-core/jvm/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala +++ b/jsoniter-scala-core/jvm/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala @@ -1019,7 +1019,7 @@ final class JsonWriter private[jsoniter_scala]( lastPos += digitCount(q0) count = lastPos } else { - val q1 = Math.multiplyHigh(q0, 184467440737L) // divide a small positive long by 100000000 + val q1 = (q0 >> 8) * 1441151881 >> 49 // divide a small positive long by 100000000 q = q1.toInt lastPos += digitCount(q1) count = write8Digits(q0 - q1 * 100000000, lastPos, buf, ds) @@ -1582,7 +1582,7 @@ final class JsonWriter private[jsoniter_scala]( private[this] def write18Digits(q0: Long, pos: Int, buf: Array[Byte], ds: Array[Short]): Int = { val q1 = Math.multiplyHigh(q0, 6189700196426901375L) >>> 25 // divide a positive long by 100000000 write8Digits(q0 - q1 * 100000000, { - val q2 = Math.multiplyHigh(q1, 184467440737L) // divide a small positive long by 100000000 + val q2 = (q1 >> 8) * 1441151881 >> 49 // divide a small positive long by 100000000 write8Digits(q1 - q2 * 100000000, write2Digits(q2.toInt, pos, buf, ds), buf, ds) }, buf, ds) } @@ -1676,7 +1676,7 @@ final class JsonWriter private[jsoniter_scala]( lastPos += digitCount(q1) lastPos } else { - val q2 = Math.multiplyHigh(q1, 184467440737L) // divide a small positive long by 100000000 + val q2 = (q1 >> 8) * 1441151881 >> 49 // divide a small positive long by 100000000 q = q2.toInt lastPos += digitCount(q2) write8Digits(q1 - q2 * 100000000, lastPos, buf, ds) diff --git a/jsoniter-scala-core/native/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala b/jsoniter-scala-core/native/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala index 6a45844e4..9437eb611 100644 --- a/jsoniter-scala-core/native/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala +++ b/jsoniter-scala-core/native/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala @@ -1019,7 +1019,7 @@ final class JsonWriter private[jsoniter_scala]( lastPos += digitCount(q0) count = lastPos } else { - val q1 = NativeMath.multiplyHigh(q0, 184467440737L) // divide a small positive long by 100000000 + val q1 = (q0 >> 8) * 1441151881 >> 49 // divide a small positive long by 100000000 q = q1.toInt lastPos += digitCount(q1) count = write8Digits(q0 - q1 * 100000000, lastPos, buf, ds) @@ -1582,7 +1582,7 @@ final class JsonWriter private[jsoniter_scala]( private[this] def write18Digits(q0: Long, pos: Int, buf: Array[Byte], ds: Array[Short]): Int = { val q1 = NativeMath.multiplyHigh(q0, 6189700196426901375L) >>> 25 // divide a positive long by 100000000 write8Digits(q0 - q1 * 100000000, { - val q2 = NativeMath.multiplyHigh(q1, 184467440737L) // divide a small positive long by 100000000 + val q2 = (q1 >> 8) * 1441151881 >> 49 // divide a small positive long by 100000000 write8Digits(q1 - q2 * 100000000, write2Digits(q2.toInt, pos, buf, ds), buf, ds) }, buf, ds) } @@ -1676,7 +1676,7 @@ final class JsonWriter private[jsoniter_scala]( lastPos += digitCount(q1) lastPos } else { - val q2 = NativeMath.multiplyHigh(q1, 184467440737L) // divide a small positive long by 100000000 + val q2 = (q1 >> 8) * 1441151881 >> 49 // divide a small positive long by 100000000 q = q2.toInt lastPos += digitCount(q2) write8Digits(q1 - q2 * 100000000, lastPos, buf, ds) diff --git a/jsoniter-scala-core/shared/src/test/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriterSpec.scala b/jsoniter-scala-core/shared/src/test/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriterSpec.scala index 6318f4897..ff6307a09 100644 --- a/jsoniter-scala-core/shared/src/test/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriterSpec.scala +++ b/jsoniter-scala-core/shared/src/test/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriterSpec.scala @@ -752,6 +752,7 @@ class JsonWriterSpec extends AnyWordSpec with Matchers with ScalaCheckPropertyCh check(BigDecimal("1E-2147483647")) check(BigDecimal("1E+2147483647")) check(BigDecimal("126.09999999999999001")) // see https://github.com/plokhotnyuk/jsoniter-scala/issues/879 + check(BigDecimal("0.0287500000000000000000")) // see https://github.com/plokhotnyuk/jsoniter-scala/issues/998 forAll(genBigInt, minSuccessful(100))(n => check(BigDecimal(n, -2147483648))) forAll(arbitrary[Double], minSuccessful(10000))(n => check(BigDecimal(n))) forAll(genBigDecimal, minSuccessful(10000))(check)