mirror of
https://github.com/json-iterator/go.git
synced 2025-02-07 19:30:06 +02:00
write float 32
This commit is contained in:
parent
e034897e69
commit
ba3c30799b
39
feature_stream_float.go
Normal file
39
feature_stream_float.go
Normal file
@ -0,0 +1,39 @@
|
||||
package jsoniter
|
||||
|
||||
import "strconv"
|
||||
|
||||
var POW10 []uint64
|
||||
|
||||
func init() {
|
||||
POW10 = []uint64{1, 10, 100, 1000, 10000, 100000, 1000000}
|
||||
}
|
||||
|
||||
func (stream *Stream) WriteFloat32(val float32) {
|
||||
if val < 0 {
|
||||
stream.writeByte('-')
|
||||
val = -val
|
||||
}
|
||||
if val > 0x4ffffff {
|
||||
stream.WriteRaw(strconv.FormatFloat(float64(val), 'f', -1, 32));
|
||||
return
|
||||
}
|
||||
precision := 6
|
||||
exp := uint64(1000000) // 6
|
||||
lval := uint64(float64(val) * float64(exp) + 0.5)
|
||||
stream.WriteUint64(lval / exp)
|
||||
fval := lval % exp
|
||||
if fval == 0 {
|
||||
return
|
||||
}
|
||||
stream.writeByte('.')
|
||||
if stream.Available() < 10 {
|
||||
stream.Flush()
|
||||
}
|
||||
for p := precision - 1; p > 0 && fval < POW10[p]; p-- {
|
||||
stream.writeByte('0')
|
||||
}
|
||||
stream.WriteUint64(fval);
|
||||
for stream.buf[stream.n - 1] == '0' {
|
||||
stream.n--;
|
||||
}
|
||||
}
|
@ -4,6 +4,9 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
"github.com/json-iterator/go/require"
|
||||
"bytes"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func Test_float64_0(t *testing.T) {
|
||||
@ -31,6 +34,30 @@ func Test_float32_1_dot_1_comma(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func Test_write_float32(t *testing.T) {
|
||||
vals := []float32{0, 1, -1, 99, 0xff, 0xfff, 0xffff, 0xfffff, 0xffffff, 0x4ffffff, 0xfffffff,
|
||||
-0x4ffffff, -0xfffffff, 1.2345, 1.23456, 1.234567, 1.001}
|
||||
for _, val := range vals {
|
||||
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
|
||||
should := require.New(t)
|
||||
buf := &bytes.Buffer{}
|
||||
stream := NewStream(buf, 4096)
|
||||
stream.WriteFloat32(val)
|
||||
stream.Flush()
|
||||
should.Nil(stream.Error)
|
||||
should.Equal(strconv.FormatFloat(float64(val), 'f', -1, 32), buf.String())
|
||||
})
|
||||
}
|
||||
should := require.New(t)
|
||||
buf := &bytes.Buffer{}
|
||||
stream := NewStream(buf, 10)
|
||||
stream.WriteRaw("abcdefg")
|
||||
stream.WriteFloat32(1.123456)
|
||||
stream.Flush()
|
||||
should.Nil(stream.Error)
|
||||
should.Equal("abcdefg1.123456", buf.String())
|
||||
}
|
||||
|
||||
func Benchmark_jsoniter_float(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
for n := 0; n < b.N; n++ {
|
||||
|
18
stream.go
18
stream.go
@ -104,7 +104,7 @@ func (b *Stream) Flush() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Stream) WriteString(s string) {
|
||||
func (b *Stream) WriteRaw(s string) {
|
||||
for len(s) > b.Available() && b.Error == nil {
|
||||
n := copy(b.buf[b.n:], s)
|
||||
b.n += n
|
||||
@ -118,6 +118,22 @@ func (b *Stream) WriteString(s string) {
|
||||
b.n += n
|
||||
}
|
||||
|
||||
func (b *Stream) WriteString(s string) {
|
||||
b.writeByte('"')
|
||||
for len(s) > b.Available() && b.Error == nil {
|
||||
n := copy(b.buf[b.n:], s)
|
||||
b.n += n
|
||||
s = s[n:]
|
||||
b.Flush()
|
||||
}
|
||||
if b.Error != nil {
|
||||
return
|
||||
}
|
||||
n := copy(b.buf[b.n:], s)
|
||||
b.n += n
|
||||
b.writeByte('"')
|
||||
}
|
||||
|
||||
func (stream *Stream) WriteNull() {
|
||||
stream.Write(bytesNull)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user