1package jsoniter 2 3import ( 4 "math" 5 "strconv" 6) 7 8var pow10 []uint64 9 10func init() { 11 pow10 = []uint64{1, 10, 100, 1000, 10000, 100000, 1000000} 12} 13 14// WriteFloat32 write float32 to stream 15func (stream *Stream) WriteFloat32(val float32) { 16 abs := math.Abs(float64(val)) 17 fmt := byte('f') 18 // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. 19 if abs != 0 { 20 if float32(abs) < 1e-6 || float32(abs) >= 1e21 { 21 fmt = 'e' 22 } 23 } 24 stream.WriteRaw(strconv.FormatFloat(float64(val), fmt, -1, 32)) 25} 26 27// WriteFloat32Lossy write float32 to stream with ONLY 6 digits precision although much much faster 28func (stream *Stream) WriteFloat32Lossy(val float32) { 29 if val < 0 { 30 stream.writeByte('-') 31 val = -val 32 } 33 if val > 0x4ffffff { 34 stream.WriteFloat32(val) 35 return 36 } 37 precision := 6 38 exp := uint64(1000000) // 6 39 lval := uint64(float64(val)*float64(exp) + 0.5) 40 stream.WriteUint64(lval / exp) 41 fval := lval % exp 42 if fval == 0 { 43 return 44 } 45 stream.writeByte('.') 46 stream.ensure(10) 47 for p := precision - 1; p > 0 && fval < pow10[p]; p-- { 48 stream.writeByte('0') 49 } 50 stream.WriteUint64(fval) 51 for stream.buf[stream.n-1] == '0' { 52 stream.n-- 53 } 54} 55 56// WriteFloat64 write float64 to stream 57func (stream *Stream) WriteFloat64(val float64) { 58 abs := math.Abs(val) 59 fmt := byte('f') 60 // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. 61 if abs != 0 { 62 if abs < 1e-6 || abs >= 1e21 { 63 fmt = 'e' 64 } 65 } 66 stream.WriteRaw(strconv.FormatFloat(float64(val), fmt, -1, 64)) 67} 68 69// WriteFloat64Lossy write float64 to stream with ONLY 6 digits precision although much much faster 70func (stream *Stream) WriteFloat64Lossy(val float64) { 71 if val < 0 { 72 stream.writeByte('-') 73 val = -val 74 } 75 if val > 0x4ffffff { 76 stream.WriteFloat64(val) 77 return 78 } 79 precision := 6 80 exp := uint64(1000000) // 6 81 lval := uint64(val*float64(exp) + 0.5) 82 stream.WriteUint64(lval / exp) 83 fval := lval % exp 84 if fval == 0 { 85 return 86 } 87 stream.writeByte('.') 88 stream.ensure(10) 89 for p := precision - 1; p > 0 && fval < pow10[p]; p-- { 90 stream.writeByte('0') 91 } 92 stream.WriteUint64(fval) 93 for stream.buf[stream.n-1] == '0' { 94 stream.n-- 95 } 96} 97