diff --git a/zio-json/native/src/main/scala/zio/json/internal/SafeNumbers.scala b/zio-json/native/src/main/scala/zio/json/internal/SafeNumbers.scala index 6ca0c36b..67eec114 100644 --- a/zio-json/native/src/main/scala/zio/json/internal/SafeNumbers.scala +++ b/zio-json/native/src/main/scala/zio/json/internal/SafeNumbers.scala @@ -134,7 +134,7 @@ object SafeNumbers { val s = vb >> 2 if ( s < 100 || { - dv = NativeMath.multiplyHigh(s, 1844674407370955168L) // divide a positive long by 10 + dv = Math.multiplyHigh(s, 1844674407370955168L) // divide a positive long by 10 val sp40 = dv * 40 val upin = (vbls - sp40).toInt (((sp40 + vbrd).toInt + 40) ^ upin) >= 0 || { @@ -315,12 +315,12 @@ object SafeNumbers { } private[this] def rop(g1: Long, g0: Long, cp: Long): Long = { - val x = NativeMath.multiplyHigh(g0, cp) + (g1 * cp >>> 1) - NativeMath.multiplyHigh(g1, cp) + (x >>> 63) | (-x ^ x) >>> 63 + val x = Math.multiplyHigh(g0, cp) + (g1 * cp >>> 1) + Math.multiplyHigh(g1, cp) + (x >>> 63) | (-x ^ x) >>> 63 } private[this] def rop(g: Long, cp: Int): Int = { - val x = NativeMath.multiplyHigh(g, cp.toLong << 32) + val x = Math.multiplyHigh(g, cp.toLong << 32) (x >>> 31).toInt | -x.toInt >>> 31 } @@ -328,13 +328,13 @@ object SafeNumbers { var q0 = x.toInt if ( q0 == x || { - q0 = (NativeMath.multiplyHigh(x, 6189700196426901375L) >>> 25).toInt // divide a positive long by 100000000 + q0 = (Math.multiplyHigh(x, 6189700196426901375L) >>> 25).toInt // divide a positive long by 100000000 (x - q0 * 100000000L).toInt == 0 } ) return stripTrailingZeros(q0).toLong var y, q1 = x while ({ - q1 = NativeMath.multiplyHigh(q1, 1844674407370955168L) // divide a positive long by 10 + q1 = Math.multiplyHigh(q1, 1844674407370955168L) // divide a positive long by 10 q1 * 10 == y }) y = q1 y @@ -368,10 +368,10 @@ object SafeNumbers { if (q0 < m1) write(q0.toInt, out) else { val m2 = 6189700196426901375L - val q1 = NativeMath.multiplyHigh(q0, m2) >>> 25 // divide a positive long by 100000000 + val q1 = Math.multiplyHigh(q0, m2) >>> 25 // divide a positive long by 100000000 if (q1 < m1) write(q1.toInt, out) else { - val q2 = NativeMath.multiplyHigh(q1, m2) >>> 25 // divide a small positive long by 100000000 + val q2 = Math.multiplyHigh(q1, m2) >>> 25 // divide a small positive long by 100000000 write(q2.toInt, out) write8Digits((q1 - q2 * m1).toInt, out) } diff --git a/zio-json/native/src/main/scala/zio/json/internal/UnsafeNumbers.scala b/zio-json/native/src/main/scala/zio/json/internal/UnsafeNumbers.scala index 3b9b9f2d..a4190815 100644 --- a/zio-json/native/src/main/scala/zio/json/internal/UnsafeNumbers.scala +++ b/zio-json/native/src/main/scala/zio/json/internal/UnsafeNumbers.scala @@ -344,12 +344,12 @@ object UnsafeNumbers { // Based on the 'Moderate Path' algorithm from the awesome library of Alexander Huszagh: https://github.com/Alexhuszagh/rust-lexical // Here is his inspiring post: https://www.reddit.com/r/rust/comments/a6j5j1/making_rust_float_parsing_fast_and_correct - @noinline private[this] def toFloat(m10: Long, e10: Int): Float = + private[this] def toFloat(m10: Long, e10: Int): Float = if (m10 == 0 || e10 < -64) 0.0f else if (e10 >= 39) Float.PositiveInfinity else { var shift = java.lang.Long.numberOfLeadingZeros(m10) - var m2 = NativeMath.unsignedMultiplyHigh(pow10Mantissas(e10 + 343), m10 << shift) + var m2 = unsignedMultiplyHigh(pow10Mantissas(e10 + 343), m10 << shift) var e2 = (e10 * 108853 >> 15) - shift + 1 // (e10 * Math.log(10) / Math.log(2)).toInt - shift + 1 shift = java.lang.Long.numberOfLeadingZeros(m2) m2 <<= shift @@ -481,7 +481,7 @@ object UnsafeNumbers { else if (e10 >= 310) Double.PositiveInfinity else { var shift = java.lang.Long.numberOfLeadingZeros(m10) - var m2 = NativeMath.unsignedMultiplyHigh(pow10Mantissas(e10 + 343), m10 << shift) + var m2 = unsignedMultiplyHigh(pow10Mantissas(e10 + 343), m10 << shift) var e2 = (e10 * 108853 >> 15) - shift + 1 // (e10 * Math.log(10) / Math.log(2)).toInt - shift + 1 shift = java.lang.Long.numberOfLeadingZeros(m2) m2 <<= shift @@ -518,6 +518,9 @@ object UnsafeNumbers { if (consume && current != -1) throw UnsafeNumber } + @inline private[this] def unsignedMultiplyHigh(x: Long, y: Long): Long = + Math.multiplyHigh(x, y) + x + y // FIXME: Use Math.unsignedMultiplyHigh after dropping of JDK 17 support + private[this] final val pow10Doubles: Array[Double] = Array(1, 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, 1e+21, 1e+22)