-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathw_float_bits.go
50 lines (45 loc) · 1.31 KB
/
w_float_bits.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package jx
import (
"math"
"strconv"
)
// Float writes float value to buffer.
func (w *Writer) Float(v float64, bits int) {
if math.IsNaN(v) || math.IsInf(v, 0) {
// Like in ECMA:
// NaN and Infinity regardless of sign are represented
// as the String null.
//
// JSON.stringify({"foo":NaN}) -> {"foo":null}
w.Null()
return
}
// From go std sources, strconv/ftoa.go:
// Convert as if by ES6 number to string conversion.
// This matches most other JSON generators.
// See golang.org/issue/6384 and golang.org/issue/14135.
// Like fmt %g, but the exponent cutoffs are different
// and exponents themselves are not padded to two digits.
b := w.Buf
abs := math.Abs(v)
fmt := byte('f')
// Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right.
if abs != 0 {
if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) {
fmt = 'e'
}
}
b = strconv.AppendFloat(b, v, fmt, -1, bits)
if fmt == 'e' {
// clean up e-09 to e-9
n := len(b)
if n >= 4 && b[n-4] == 'e' && b[n-3] == '-' && b[n-2] == '0' {
b[n-2] = b[n-1]
b = b[:n-1]
}
}
w.Buf = b
}