diff options
Diffstat (limited to 'vendor/github.com/json-iterator/go/stream_float.go')
-rw-r--r-- | vendor/github.com/json-iterator/go/stream_float.go | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/vendor/github.com/json-iterator/go/stream_float.go b/vendor/github.com/json-iterator/go/stream_float.go new file mode 100644 index 0000000..826aa59 --- /dev/null +++ b/vendor/github.com/json-iterator/go/stream_float.go | |||
@@ -0,0 +1,111 @@ | |||
1 | package jsoniter | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | "math" | ||
6 | "strconv" | ||
7 | ) | ||
8 | |||
9 | var pow10 []uint64 | ||
10 | |||
11 | func init() { | ||
12 | pow10 = []uint64{1, 10, 100, 1000, 10000, 100000, 1000000} | ||
13 | } | ||
14 | |||
15 | // WriteFloat32 write float32 to stream | ||
16 | func (stream *Stream) WriteFloat32(val float32) { | ||
17 | if math.IsInf(float64(val), 0) || math.IsNaN(float64(val)) { | ||
18 | stream.Error = fmt.Errorf("unsupported value: %f", val) | ||
19 | return | ||
20 | } | ||
21 | abs := math.Abs(float64(val)) | ||
22 | fmt := byte('f') | ||
23 | // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. | ||
24 | if abs != 0 { | ||
25 | if float32(abs) < 1e-6 || float32(abs) >= 1e21 { | ||
26 | fmt = 'e' | ||
27 | } | ||
28 | } | ||
29 | stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 32) | ||
30 | } | ||
31 | |||
32 | // WriteFloat32Lossy write float32 to stream with ONLY 6 digits precision although much much faster | ||
33 | func (stream *Stream) WriteFloat32Lossy(val float32) { | ||
34 | if math.IsInf(float64(val), 0) || math.IsNaN(float64(val)) { | ||
35 | stream.Error = fmt.Errorf("unsupported value: %f", val) | ||
36 | return | ||
37 | } | ||
38 | if val < 0 { | ||
39 | stream.writeByte('-') | ||
40 | val = -val | ||
41 | } | ||
42 | if val > 0x4ffffff { | ||
43 | stream.WriteFloat32(val) | ||
44 | return | ||
45 | } | ||
46 | precision := 6 | ||
47 | exp := uint64(1000000) // 6 | ||
48 | lval := uint64(float64(val)*float64(exp) + 0.5) | ||
49 | stream.WriteUint64(lval / exp) | ||
50 | fval := lval % exp | ||
51 | if fval == 0 { | ||
52 | return | ||
53 | } | ||
54 | stream.writeByte('.') | ||
55 | for p := precision - 1; p > 0 && fval < pow10[p]; p-- { | ||
56 | stream.writeByte('0') | ||
57 | } | ||
58 | stream.WriteUint64(fval) | ||
59 | for stream.buf[len(stream.buf)-1] == '0' { | ||
60 | stream.buf = stream.buf[:len(stream.buf)-1] | ||
61 | } | ||
62 | } | ||
63 | |||
64 | // WriteFloat64 write float64 to stream | ||
65 | func (stream *Stream) WriteFloat64(val float64) { | ||
66 | if math.IsInf(val, 0) || math.IsNaN(val) { | ||
67 | stream.Error = fmt.Errorf("unsupported value: %f", val) | ||
68 | return | ||
69 | } | ||
70 | abs := math.Abs(val) | ||
71 | fmt := byte('f') | ||
72 | // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. | ||
73 | if abs != 0 { | ||
74 | if abs < 1e-6 || abs >= 1e21 { | ||
75 | fmt = 'e' | ||
76 | } | ||
77 | } | ||
78 | stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 64) | ||
79 | } | ||
80 | |||
81 | // WriteFloat64Lossy write float64 to stream with ONLY 6 digits precision although much much faster | ||
82 | func (stream *Stream) WriteFloat64Lossy(val float64) { | ||
83 | if math.IsInf(val, 0) || math.IsNaN(val) { | ||
84 | stream.Error = fmt.Errorf("unsupported value: %f", val) | ||
85 | return | ||
86 | } | ||
87 | if val < 0 { | ||
88 | stream.writeByte('-') | ||
89 | val = -val | ||
90 | } | ||
91 | if val > 0x4ffffff { | ||
92 | stream.WriteFloat64(val) | ||
93 | return | ||
94 | } | ||
95 | precision := 6 | ||
96 | exp := uint64(1000000) // 6 | ||
97 | lval := uint64(val*float64(exp) + 0.5) | ||
98 | stream.WriteUint64(lval / exp) | ||
99 | fval := lval % exp | ||
100 | if fval == 0 { | ||
101 | return | ||
102 | } | ||
103 | stream.writeByte('.') | ||
104 | for p := precision - 1; p > 0 && fval < pow10[p]; p-- { | ||
105 | stream.writeByte('0') | ||
106 | } | ||
107 | stream.WriteUint64(fval) | ||
108 | for stream.buf[len(stream.buf)-1] == '0' { | ||
109 | stream.buf = stream.buf[:len(stream.buf)-1] | ||
110 | } | ||
111 | } | ||