diff --git a/feature_any_string.go b/feature_any_string.go index c58dda2..13c9ad0 100644 --- a/feature_any_string.go +++ b/feature_any_string.go @@ -119,13 +119,51 @@ func (any *stringAny) ToUint64() uint64 { } func (any *stringAny) ToFloat32() float32 { - parsed, _ := strconv.ParseFloat(any.val, 32) - return float32(parsed) + return float32(any.ToFloat64()) } func (any *stringAny) ToFloat64() float64 { - parsed, _ := strconv.ParseFloat(any.val, 64) - return parsed + if any.val == "" { + return 0 + } + + startPos := 0 + endPos := 0 + flag := 1 + + if any.val[0] == '+' || any.val[0] == '-' { + startPos = 1 + } + + if any.val[0] == '-' { + flag = -1 + } + + pointOccurCnt := 0 + pointPos := -1 + + for i := startPos; i < len(any.val); i++ { + if any.val[i] >= '0' && any.val[i] <= '9' { + endPos = i + 1 + } else if any.val[i] == '.' && pointOccurCnt == 0 { + endPos = i + 1 + pointOccurCnt++ + pointPos = i + } else { + break + } + } + + if pointPos == endPos-1 { + endPos-- + } + + if endPos <= startPos { + return 0 + } + + parsed, _ := strconv.ParseFloat(any.val[startPos:endPos], 64) + return float64(flag) * parsed } func (any *stringAny) ToString() string { diff --git a/jsoniter_any_float_test.go b/jsoniter_any_float_test.go index 6606956..4e892e6 100644 --- a/jsoniter_any_float_test.go +++ b/jsoniter_any_float_test.go @@ -1,10 +1,51 @@ package jsoniter import ( - "github.com/json-iterator/go/require" "testing" + + "github.com/json-iterator/go/require" ) +var floatConvertMap = map[string]float64{ + "null": 0, + "true": 1, + "false": 0, + + `"true"`: 0, + `"false"`: 0, + + "123": 123, + `"123true"`: 123, + + `"-123true"`: -123, + "0": 0, + `"0"`: 0, + "-1": -1, + + "1.1": 1.1, + "0.0": 0, + "-1.1": -1.1, + `"+1.1"`: 1.1, + `""`: 0, + "[1,2]": 1, + "[]": 0, + "{}": 0, + `{"abc":1}`: 0, +} + +func Test_read_any_to_float(t *testing.T) { + should := require.New(t) + for k, v := range floatConvertMap { + any := Get([]byte(k)) + should.Equal(float64(v), any.ToFloat64(), "the original val is "+k) + } + + for k, v := range floatConvertMap { + any := Get([]byte(k)) + should.Equal(float32(v), any.ToFloat32(), "the original val is "+k) + } +} + func Test_read_float_as_any(t *testing.T) { should := require.New(t) any := Get([]byte("12.3")) diff --git a/jsoniter_any_int_test.go b/jsoniter_any_int_test.go index 4341cb1..3a208c7 100644 --- a/jsoniter_any_int_test.go +++ b/jsoniter_any_int_test.go @@ -25,12 +25,14 @@ var intConvertMap = map[string]int{ `"false"`: 0, `"true123"`: 0, `"123true"`: 123, + `"-123true"`: -123, `"1.2332e6"`: 1, `""`: 0, "+": 0, "-": 0, "[]": 0, "[1,2]": 1, + `["1","2"]`: 1, // object in php cannot convert to int "{}": 0, } @@ -73,6 +75,7 @@ var uintConvertMap = map[string]int{ `"true"`: 0, `"false"`: 0, `"true123"`: 0, + `"+1"`: 1, `"123true"`: 123, `"-123true"`: 0, `"1.2332e6"`: 1,