github.com/nuvolaris/goja@v0.0.0-20230825100449-967811910c6d/ftoa/common.go (about) 1 /* 2 Package ftoa provides ECMAScript-compliant floating point number conversion to string. 3 4 It contains code ported from Rhino (https://github.com/mozilla/rhino/blob/master/src/org/mozilla/javascript/DToA.java) 5 as well as from the original code by David M. Gay. 6 7 See LICENSE_LUCENE for the original copyright message and disclaimer. 8 */ 9 package ftoa 10 11 import ( 12 "math" 13 ) 14 15 const ( 16 frac_mask = 0xfffff 17 exp_shift = 20 18 exp_msk1 = 0x100000 19 20 exp_shiftL = 52 21 exp_mask_shifted = 0x7ff 22 frac_maskL = 0xfffffffffffff 23 exp_msk1L = 0x10000000000000 24 exp_shift1 = 20 25 exp_mask = 0x7ff00000 26 bias = 1023 27 p = 53 28 bndry_mask = 0xfffff 29 log2P = 1 30 ) 31 32 func lo0bits(x uint32) (k int) { 33 34 if (x & 7) != 0 { 35 if (x & 1) != 0 { 36 return 0 37 } 38 if (x & 2) != 0 { 39 return 1 40 } 41 return 2 42 } 43 if (x & 0xffff) == 0 { 44 k = 16 45 x >>= 16 46 } 47 if (x & 0xff) == 0 { 48 k += 8 49 x >>= 8 50 } 51 if (x & 0xf) == 0 { 52 k += 4 53 x >>= 4 54 } 55 if (x & 0x3) == 0 { 56 k += 2 57 x >>= 2 58 } 59 if (x & 1) == 0 { 60 k++ 61 x >>= 1 62 if (x & 1) == 0 { 63 return 32 64 } 65 } 66 return 67 } 68 69 func hi0bits(x uint32) (k int) { 70 71 if (x & 0xffff0000) == 0 { 72 k = 16 73 x <<= 16 74 } 75 if (x & 0xff000000) == 0 { 76 k += 8 77 x <<= 8 78 } 79 if (x & 0xf0000000) == 0 { 80 k += 4 81 x <<= 4 82 } 83 if (x & 0xc0000000) == 0 { 84 k += 2 85 x <<= 2 86 } 87 if (x & 0x80000000) == 0 { 88 k++ 89 if (x & 0x40000000) == 0 { 90 return 32 91 } 92 } 93 return 94 } 95 96 func stuffBits(bits []byte, offset int, val uint32) { 97 bits[offset] = byte(val >> 24) 98 bits[offset+1] = byte(val >> 16) 99 bits[offset+2] = byte(val >> 8) 100 bits[offset+3] = byte(val) 101 } 102 103 func d2b(d float64, b []byte) (e, bits int, dblBits []byte) { 104 dBits := math.Float64bits(d) 105 d0 := uint32(dBits >> 32) 106 d1 := uint32(dBits) 107 108 z := d0 & frac_mask 109 d0 &= 0x7fffffff /* clear sign bit, which we ignore */ 110 111 var de, k, i int 112 if de = int(d0 >> exp_shift); de != 0 { 113 z |= exp_msk1 114 } 115 116 y := d1 117 if y != 0 { 118 dblBits = b[:8] 119 k = lo0bits(y) 120 y >>= k 121 if k != 0 { 122 stuffBits(dblBits, 4, y|z<<(32-k)) 123 z >>= k 124 } else { 125 stuffBits(dblBits, 4, y) 126 } 127 stuffBits(dblBits, 0, z) 128 if z != 0 { 129 i = 2 130 } else { 131 i = 1 132 } 133 } else { 134 dblBits = b[:4] 135 k = lo0bits(z) 136 z >>= k 137 stuffBits(dblBits, 0, z) 138 k += 32 139 i = 1 140 } 141 142 if de != 0 { 143 e = de - bias - (p - 1) + k 144 bits = p - k 145 } else { 146 e = de - bias - (p - 1) + 1 + k 147 bits = 32*i - hi0bits(z) 148 } 149 return 150 }