1
0
mirror of https://github.com/json-iterator/go.git synced 2025-01-05 12:50:34 +02:00

fix lossy float marshal and omit empty

This commit is contained in:
Tao Wen 2017-06-20 07:51:38 +08:00
parent 945fe53724
commit 39c9bb226a
2 changed files with 43 additions and 8 deletions

View File

@ -99,18 +99,42 @@ func (cfg *frozenConfig) supportUnexportedStructFields() {
})
}
type lossyFloat32Encoder struct {
}
func (encoder *lossyFloat32Encoder) encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteFloat32Lossy(*((*float32)(ptr)))
}
func (encoder *lossyFloat32Encoder) encodeInterface(val interface{}, stream *Stream) {
writeToStream(val, stream, encoder)
}
func (encoder *lossyFloat32Encoder) isEmpty(ptr unsafe.Pointer) bool {
return *((*float32)(ptr)) == 0
}
type lossyFloat64Encoder struct {
}
func (encoder *lossyFloat64Encoder) encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteFloat64Lossy(*((*float64)(ptr)))
}
func (encoder *lossyFloat64Encoder) encodeInterface(val interface{}, stream *Stream) {
writeToStream(val, stream, encoder)
}
func (encoder *lossyFloat64Encoder) isEmpty(ptr unsafe.Pointer) bool {
return *((*float64)(ptr)) == 0
}
// EnableLossyFloatMarshalling keeps 10**(-6) precision
// for float variables for better performance.
func (cfg *frozenConfig) marshalFloatWith6Digits() {
// for better performance
cfg.addEncoderToCache(reflect.TypeOf((*float32)(nil)).Elem(), &funcEncoder{func(ptr unsafe.Pointer, stream *Stream) {
val := *((*float32)(ptr))
stream.WriteFloat32Lossy(val)
}})
cfg.addEncoderToCache(reflect.TypeOf((*float64)(nil)).Elem(), &funcEncoder{func(ptr unsafe.Pointer, stream *Stream) {
val := *((*float64)(ptr))
stream.WriteFloat64Lossy(val)
}})
cfg.addEncoderToCache(reflect.TypeOf((*float32)(nil)).Elem(), &lossyFloat32Encoder{})
cfg.addEncoderToCache(reflect.TypeOf((*float64)(nil)).Elem(), &lossyFloat64Encoder{})
}
type htmlEscapedStringEncoder struct {

View File

@ -162,6 +162,17 @@ func Test_read_float_scientific(t *testing.T) {
should.Equal(float64(10), obj)
}
func Test_lossy_float_marshal(t *testing.T) {
should := require.New(t)
api := Config{MarshalFloatWith6Digits: true}.Froze()
output, err := api.MarshalToString(float64(0.1234567))
should.Nil(err)
should.Equal("0.123457", output)
output, err = api.MarshalToString(float32(0.1234567))
should.Nil(err)
should.Equal("0.123457", output)
}
func Benchmark_jsoniter_float(b *testing.B) {
b.ReportAllocs()
input := []byte(`1.1123,`)