From 2c0efb7f9aa9c2d8382c145fdab1dbb5bd068d28 Mon Sep 17 00:00:00 2001 From: francoispqt Date: Mon, 10 Jun 2019 23:14:03 +0800 Subject: [PATCH] enable decoding of float32 when >= 10 decimal --- decode_number_float.go | 20 ++++++++++---------- decode_number_float_test.go | 5 +++++ decode_number_int.go | 1 + 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/decode_number_float.go b/decode_number_float.go index 0ac1a82..f76c586 100644 --- 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 index 4ee6dbe..94deaff 100644 --- a/decode_number_float_test.go +++ b/decode_number_float_test.go @@ -873,6 +873,11 @@ func TestDecoderFloat32(t *testing.T) { json: "-0.1234", expectedResult: -0.1234, }, + { + name: "float10-digit-decimal", + json: "0.9833984375", + expectedResult: 0.9833984, + }, { name: "error", json: "83zez4", diff --git a/decode_number_int.go b/decode_number_int.go index 9501904..8429049 100644 --- 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++ {