Browse Source

fix lossy float marshal and omit empty

Tao Wen 8 years ago
parent
commit
39c9bb226a
2 changed files with 43 additions and 8 deletions
  1. 32 8
      feature_config.go
  2. 11 0
      jsoniter_float_test.go

+ 32 - 8
feature_config.go

@@ -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 {

+ 11 - 0
jsoniter_float_test.go

@@ -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,`)