@@ -158,7 +158,7 @@ private fun decimalCount64High(value: ULong): Int {
158
158
159
159
private const val MAX_DOUBLE_LENGTH = 28
160
160
161
- internal fun dtoa (value : Double ): String {
161
+ internal fun dtoa (value : Double , isSinglePrecision : Boolean ): String {
162
162
if (value == 0.0 ) {
163
163
return if (value.toRawBits() == 0L ) " 0.0" else " -0.0"
164
164
}
@@ -169,21 +169,21 @@ internal fun dtoa(value: Double): String {
169
169
}
170
170
171
171
val buf = WasmCharArray (MAX_DOUBLE_LENGTH )
172
- val size = dtoaCore(buf, value)
172
+ val size = dtoaCore(buf, value, isSinglePrecision )
173
173
val ret = WasmCharArray (size)
174
174
buf.copyInto(ret, 0 , 0 , size)
175
175
return ret.createString()
176
176
}
177
177
178
- private fun dtoaCore (buffer : WasmCharArray , valueInp : Double ): Int {
178
+ private fun dtoaCore (buffer : WasmCharArray , valueInp : Double , isSinglePrecision : Boolean ): Int {
179
179
var value = valueInp
180
180
181
181
val sign = (value < 0 ).toInt()
182
182
if (sign == 1 ) {
183
183
value = - value
184
184
buffer.set(0 , CharCodes .MINUS .code.toChar())
185
185
}
186
- var len = grisu2(value, buffer, sign)
186
+ var len = grisu2(value, buffer, sign, isSinglePrecision )
187
187
len = prettify(BufferWithOffset (buffer, sign), len - sign, _K )
188
188
return len + sign
189
189
}
@@ -235,15 +235,36 @@ private val FRC_POWERS = longArrayOf(
235
235
0x9E19DB92B4E31BA9UL .toLong(), 0xEB96BF6EBADF77D9UL .toLong(), 0xAF87023B9BF0EE6BUL .toLong()
236
236
)
237
237
238
- private fun grisu2 (value : Double , buffer : WasmCharArray , sign : Int ): Int {
238
+ private const val SINGLE_SIGNIFICANT_MASK = 0x007FFFFF
239
+ private const val SINGLE_EXPONENT_MASK = 0x7F800000
240
+ private const val SINGLE_SIGNIFICANT_SIZE = 23 // Excluding hidden bit
241
+ private const val SINGLE_EXPONENT_BIAS = 0x7F + SINGLE_SIGNIFICANT_SIZE
242
+
243
+ private const val DOUBLE_SIGNIFICANT_MASK = 0x000FFFFFFFFFFFFFL
244
+ private const val DOUBLE_EXPONENT_MASK = 0x7FF0000000000000L
245
+ private const val DOUBLE_SIGNIFICANT_SIZE = 52 // Excluding hidden bit
246
+ private const val DOUBLE_EXPONENT_BIAS = 0x3FF + DOUBLE_SIGNIFICANT_SIZE
247
+
248
+ private fun grisu2 (value : Double , buffer : WasmCharArray , sign : Int , isSinglePrecision : Boolean ): Int {
249
+ var frc: Long
250
+ var exp: Int
251
+
239
252
// frexp routine
240
- val uv = value.toBits()
241
- var exp = ((uv and 0x7FF0000000000000 ) ushr 52 ).toInt()
242
- val sid = uv and 0x000FFFFFFFFFFFFF
243
- var frc = ((exp != 0 ).toLong() shl 52 ) + sid
244
- exp = (if (exp != 0 ) exp else 1 ) - (0x3FF + 52 )
253
+ if (isSinglePrecision) {
254
+ val uv = value.toFloat().toBits()
255
+ exp = (uv and SINGLE_EXPONENT_MASK ) ushr SINGLE_SIGNIFICANT_SIZE
256
+ val sid = uv and SINGLE_SIGNIFICANT_MASK
257
+ frc = ((exp != 0 ).toLong() shl SINGLE_SIGNIFICANT_SIZE ) + sid
258
+ exp = (if (exp != 0 ) exp else 1 ) - SINGLE_EXPONENT_BIAS
259
+ } else {
260
+ val uv = value.toBits()
261
+ exp = ((uv and DOUBLE_EXPONENT_MASK ) ushr DOUBLE_SIGNIFICANT_SIZE ).toInt()
262
+ val sid = uv and DOUBLE_SIGNIFICANT_MASK
263
+ frc = ((exp != 0 ).toLong() shl DOUBLE_SIGNIFICANT_SIZE ) + sid
264
+ exp = (if (exp != 0 ) exp else 1 ) - DOUBLE_EXPONENT_BIAS
265
+ }
245
266
246
- normalizedBoundaries(frc, exp)
267
+ normalizedBoundaries(frc, exp, isSinglePrecision )
247
268
getCachedPower(_exp )
248
269
249
270
// normalize
@@ -288,14 +309,15 @@ private fun umul64e(e1: Int, e2: Int): Int {
288
309
return e1 + e2 + 64 // where 64 is significand size
289
310
}
290
311
291
- private fun normalizedBoundaries (f : Long , e : Int ) {
312
+ private fun normalizedBoundaries (f : Long , e : Int , isSinglePrecision : Boolean ) {
292
313
var frc = (f shl 1 ) + 1
293
314
var exp = e - 1
294
315
val off = frc.countLeadingZeroBits()
295
316
frc = frc shl off
296
317
exp - = off
297
318
298
- val m = 1 + (f == 0x0010000000000000 ).toInt()
319
+ val smallestNormalizedSignificand: Long = if (isSinglePrecision) 0x00800000 else 0x0010000000000000
320
+ val m = 1 + (f == smallestNormalizedSignificand).toInt()
299
321
300
322
_frc_plus = frc
301
323
_frc_minus = ((f shl m) - 1 ) shl e - m - exp
0 commit comments