1
0
mirror of https://github.com/json-iterator/go.git synced 2025-01-29 19:14:05 +02:00

fix write float compatibility

This commit is contained in:
Tao Wen 2017-07-02 15:11:36 +08:00
parent c4f54740f7
commit c009421781
3 changed files with 28 additions and 6 deletions

View File

@ -2,6 +2,7 @@ package jsoniter
import (
"strconv"
"math"
)
var _POW10 []uint64
@ -11,7 +12,15 @@ func init() {
}
func (stream *Stream) WriteFloat32(val float32) {
stream.WriteRaw(strconv.FormatFloat(float64(val), 'f', -1, 32))
abs := math.Abs(float64(val))
fmt := byte('f')
// Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right.
if abs != 0 {
if float32(abs) < 1e-6 || float32(abs) >= 1e21 {
fmt = 'e'
}
}
stream.WriteRaw(strconv.FormatFloat(float64(val), fmt, -1, 32))
}
func (stream *Stream) WriteFloat32Lossy(val float32) {
@ -20,7 +29,7 @@ func (stream *Stream) WriteFloat32Lossy(val float32) {
val = -val
}
if val > 0x4ffffff {
stream.WriteRaw(strconv.FormatFloat(float64(val), 'f', -1, 32))
stream.WriteFloat32(val)
return
}
precision := 6
@ -43,7 +52,15 @@ func (stream *Stream) WriteFloat32Lossy(val float32) {
}
func (stream *Stream) WriteFloat64(val float64) {
stream.WriteRaw(strconv.FormatFloat(float64(val), 'f', -1, 64))
abs := math.Abs(val)
fmt := byte('f')
// Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right.
if abs != 0 {
if abs < 1e-6 || abs >= 1e21 {
fmt = 'e'
}
}
stream.WriteRaw(strconv.FormatFloat(float64(val), fmt, -1, 64))
}
func (stream *Stream) WriteFloat64Lossy(val float64) {
@ -52,7 +69,7 @@ func (stream *Stream) WriteFloat64Lossy(val float64) {
val = -val
}
if val > 0x4ffffff {
stream.WriteRaw(strconv.FormatFloat(val, 'f', -1, 64))
stream.WriteFloat64(val)
return
}
precision := 6

View File

@ -1,4 +1,5 @@
// +build go1.8
package jsoniter
import (

View File

@ -85,7 +85,9 @@ func Test_write_float32(t *testing.T) {
stream.WriteFloat32Lossy(val)
stream.Flush()
should.Nil(stream.Error)
should.Equal(strconv.FormatFloat(float64(val), 'f', -1, 32), buf.String())
output, err := json.Marshal(val)
should.Nil(err)
should.Equal(string(output), buf.String())
})
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t)
@ -94,7 +96,9 @@ func Test_write_float32(t *testing.T) {
stream.WriteVal(val)
stream.Flush()
should.Nil(stream.Error)
should.Equal(strconv.FormatFloat(float64(val), 'f', -1, 32), buf.String())
output, err := json.Marshal(val)
should.Nil(err)
should.Equal(string(output), buf.String())
})
}
should := require.New(t)