gojay

high performance JSON encoder/decoder with stream API for Golang
git clone git://git.lair.cx/gojay
Log | Files | Refs | README | LICENSE

commit 2c0efb7f9aa9c2d8382c145fdab1dbb5bd068d28
parent c53b22ca557f52a56b71c24b663e8a48d6150440
Author: francoispqt <francois@parquet.ninja>
Date:   Mon, 10 Jun 2019 23:14:03 +0800

enable decoding of float32 when >= 10 decimal

Diffstat:
Mdecode_number_float.go | 20++++++++++----------
Mdecode_number_float_test.go | 5+++++
Mdecode_number_int.go | 1+
3 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/decode_number_float.go b/decode_number_float.go @@ -324,7 +324,7 @@ func (dec *Decoder) getFloat32() (float32, error) { continue case '.': // we get part before decimal as integer - beforeDecimal := dec.atoi32(start, end) + beforeDecimal := dec.atoi64(start, end) // then we get part after decimal as integer start = j + 1 // get number after the decimal point @@ -341,14 +341,14 @@ func (dec *Decoder) getFloat32() (float32, error) { continue } else if (c == 'e' || c == 'E') && j < i-1 { // we get the number before decimal - var afterDecimal int32 + var afterDecimal int64 expI := end - start + 2 // if exp is too long, it means number is too long, just truncate the number if expI >= 12 || expI < 0 { expI = 10 - afterDecimal = dec.atoi32(start, start+expI-2) + afterDecimal = dec.atoi64(start, start+expI-2) } else { - afterDecimal = dec.atoi32(start, end) + afterDecimal = dec.atoi64(start, end) } dec.cursor = i + 1 pow := pow10uint64[expI] @@ -377,23 +377,23 @@ func (dec *Decoder) getFloat32() (float32, error) { } // then we add both integers // then we divide the number by the power found - var afterDecimal int32 + var afterDecimal int64 expI := end - start + 2 // if exp is too long, it means number is too long, just truncate the number if expI >= 12 || expI < 0 { expI = 10 - afterDecimal = dec.atoi32(start, start+expI-2) + afterDecimal = dec.atoi64(start, start+expI-2) } else { // then we add both integers // then we divide the number by the power found - afterDecimal = dec.atoi32(start, end) + afterDecimal = dec.atoi64(start, end) } pow := pow10uint64[expI] return float32(beforeDecimal+afterDecimal) / float32(pow), nil case 'e', 'E': dec.cursor = j + 1 // we get part before decimal as integer - beforeDecimal := uint32(dec.atoi32(start, end)) + beforeDecimal := dec.atoi64(start, end) // get exponent exp, err := dec.getExponent() if err != nil { @@ -410,12 +410,12 @@ func (dec *Decoder) getFloat32() (float32, error) { return float32(beforeDecimal) * float32(pow10uint64[pExp]), nil case ' ', '\n', '\t', '\r', ',', '}', ']': // does not have decimal dec.cursor = j - return float32(dec.atoi32(start, end)), nil + return float32(dec.atoi64(start, end)), nil } // invalid json we expect numbers, dot (single one), comma, or spaces return 0, dec.raiseInvalidJSONErr(dec.cursor) } - return float32(dec.atoi32(start, end)), nil + return float32(dec.atoi64(start, end)), nil } // Add Values functions diff --git a/decode_number_float_test.go b/decode_number_float_test.go @@ -874,6 +874,11 @@ func TestDecoderFloat32(t *testing.T) { expectedResult: -0.1234, }, { + name: "float10-digit-decimal", + json: "0.9833984375", + expectedResult: 0.9833984, + }, + { name: "error", json: "83zez4", expectedResult: 0, diff --git a/decode_number_int.go b/decode_number_int.go @@ -1070,6 +1070,7 @@ func (dec *Decoder) atoi32(start, end int) int32 { var ll = end + 1 - start var val = int32(digits[dec.data[start]]) end = end + 1 + // overflowing if ll < maxInt32Length { for i := start + 1; i < end; i++ {