/* Package ftoa provides ECMAScript-compliant floating point number conversion to string. It contains code ported from Rhino (https://github.com/mozilla/rhino/blob/master/src/org/mozilla/javascript/DToA.java) as well as from the original code by David M. Gay. See LICENSE_LUCENE for the original copyright message and disclaimer. */ package ftoa import ( "math" ) const ( frac_mask = 0xfffff exp_shift = 20 exp_msk1 = 0x100000 exp_shiftL = 52 exp_mask_shifted = 0x7ff frac_maskL = 0xfffffffffffff exp_msk1L = 0x10000000000000 exp_shift1 = 20 exp_mask = 0x7ff00000 bias = 1023 p = 53 bndry_mask = 0xfffff log2P = 1 ) func lo0bits(x uint32) (k int) { if (x & 7) != 0 { if (x & 1) != 0 { return 0 } if (x & 2) != 0 { return 1 } return 2 } if (x & 0xffff) == 0 { k = 16 x >>= 16 } if (x & 0xff) == 0 { k += 8 x >>= 8 } if (x & 0xf) == 0 { k += 4 x >>= 4 } if (x & 0x3) == 0 { k += 2 x >>= 2 } if (x & 1) == 0 { k++ x >>= 1 if (x & 1) == 0 { return 32 } } return } func hi0bits(x uint32) (k int) { if (x & 0xffff0000) == 0 { k = 16 x <<= 16 } if (x & 0xff000000) == 0 { k += 8 x <<= 8 } if (x & 0xf0000000) == 0 { k += 4 x <<= 4 } if (x & 0xc0000000) == 0 { k += 2 x <<= 2 } if (x & 0x80000000) == 0 { k++ if (x & 0x40000000) == 0 { return 32 } } return } func stuffBits(bits []byte, offset int, val uint32) { bits[offset] = byte(val >> 24) bits[offset+1] = byte(val >> 16) bits[offset+2] = byte(val >> 8) bits[offset+3] = byte(val) } func d2b(d float64, b []byte) (e, bits int, dblBits []byte) { dBits := math.Float64bits(d) d0 := uint32(dBits >> 32) d1 := uint32(dBits) z := d0 & frac_mask d0 &= 0x7fffffff /* clear sign bit, which we ignore */ var de, k, i int if de = int(d0 >> exp_shift); de != 0 { z |= exp_msk1 } y := d1 if y != 0 { dblBits = b[:8] k = lo0bits(y) y >>= k if k != 0 { stuffBits(dblBits, 4, y|z<<(32-k)) z >>= k } else { stuffBits(dblBits, 4, y) } stuffBits(dblBits, 0, z) if z != 0 { i = 2 } else { i = 1 } } else { dblBits = b[:4] k = lo0bits(z) z >>= k stuffBits(dblBits, 0, z) k += 32 i = 1 } if de != 0 { e = de - bias - (p - 1) + k bits = p - k } else { e = de - bias - (p - 1) + 1 + k bits = 32*i - hi0bits(z) } return }