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