Skip to content

Commit

Permalink
fix: parse max float32 (#461)
Browse files Browse the repository at this point in the history
  • Loading branch information
liuq19 authored Jun 21, 2023
1 parent 7a19e81 commit 3ed2c48
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 16 deletions.
14 changes: 6 additions & 8 deletions internal/decoder/assembler_amd64_go116.go
Original file line number Diff line number Diff line change
Expand Up @@ -818,8 +818,8 @@ var (
)

var (
_Vp_max_f32 = new(float64)
_Vp_min_f32 = new(float64)
_Vp_max_f32 = new(float32)
_Vp_min_f32 = new(float32)
)

func init() {
Expand All @@ -828,17 +828,15 @@ func init() {
}

func (self *_Assembler) range_single() {
self.Emit("MOVSD" , _VAR_st_Dv, _X0) // MOVSD st.Dv, X0
self.Emit("CVTSD2SS", _VAR_st_Dv, _X0) // CVTSD2SS st.Dv, X0
self.Emit("MOVQ" , _V_max_f32, _AX) // MOVQ _max_f32, AX
self.Emit("MOVQ" , jit.Gitab(_I_float32), _ET) // MOVQ ${itab(float32)}, ET
self.Emit("MOVQ" , jit.Gtype(_T_float32), _EP) // MOVQ ${type(float32)}, EP
self.Emit("UCOMISD" , jit.Ptr(_AX, 0), _X0) // UCOMISD (AX), X0
self.Emit("UCOMISS" , jit.Ptr(_AX, 0), _X0) // UCOMISS (AX), X0
self.Sjmp("JA" , _LB_range_error) // JA _range_error
self.Emit("MOVQ" , _V_min_f32, _AX) // MOVQ _min_f32, AX
self.Emit("MOVSD" , jit.Ptr(_AX, 0), _X1) // MOVSD (AX), X1
self.Emit("UCOMISD" , _X0, _X1) // UCOMISD X0, X1
self.Sjmp("JA" , _LB_range_error) // JA _range_error
self.Emit("CVTSD2SS", _X0, _X0) // CVTSD2SS X0, X0
self.Emit("UCOMISS" , jit.Ptr(_AX, 0), _X0) // UCOMISS (AX), X0
self.Sjmp("JB" , _LB_range_error) // JB _range_error
}

func (self *_Assembler) range_signed(i *rt.GoItab, t *rt.GoType, a int64, b int64) {
Expand Down
14 changes: 6 additions & 8 deletions internal/decoder/assembler_amd64_go117.go
Original file line number Diff line number Diff line change
Expand Up @@ -825,8 +825,8 @@ var (
)

var (
_Vp_max_f32 = new(float64)
_Vp_min_f32 = new(float64)
_Vp_max_f32 = new(float32)
_Vp_min_f32 = new(float32)
)

func init() {
Expand All @@ -835,17 +835,15 @@ func init() {
}

func (self *_Assembler) range_single_X0() {
self.Emit("MOVSD" , _VAR_st_Dv, _X0) // MOVSD st.Dv, X0
self.Emit("CVTSD2SS", _VAR_st_Dv, _X0) // CVTSD2SS _VAR_st_Dv, X0
self.Emit("MOVQ" , _V_max_f32, _CX) // MOVQ _max_f32, CX
self.Emit("MOVQ" , jit.Gitab(_I_float32), _ET) // MOVQ ${itab(float32)}, ET
self.Emit("MOVQ" , jit.Gtype(_T_float32), _EP) // MOVQ ${type(float32)}, EP
self.Emit("UCOMISD" , jit.Ptr(_CX, 0), _X0) // UCOMISD (CX), X0
self.Emit("UCOMISS" , jit.Ptr(_CX, 0), _X0) // UCOMISS (CX), X0
self.Sjmp("JA" , _LB_range_error) // JA _range_error
self.Emit("MOVQ" , _V_min_f32, _CX) // MOVQ _min_f32, CX
self.Emit("MOVSD" , jit.Ptr(_CX, 0), _X1) // MOVSD (CX), X1
self.Emit("UCOMISD" , _X0, _X1) // UCOMISD X0, X1
self.Sjmp("JA" , _LB_range_error) // JA _range_error
self.Emit("CVTSD2SS", _X0, _X0) // CVTSD2SS X0, X0
self.Emit("UCOMISS" , jit.Ptr(_CX, 0), _X0) // UCOMISS (CX), X0
self.Sjmp("JB" , _LB_range_error) // JB _range_error
}

func (self *_Assembler) range_signed_CX(i *rt.GoItab, t *rt.GoType, a int64, b int64) {
Expand Down
64 changes: 64 additions & 0 deletions issue_test/issue460_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/**
* Copyright 2023 ByteDance Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express orimplied.
* See the License for the specific language governing permissionsand
* limitations under the License.
*/
package issue_test
import (
`encoding/json`
`testing`
`github.com/bytedance/sonic`
`github.com/stretchr/testify/require`
)

func TestIssue460_UnmarshalMaxFloat32(t *testing.T) {
tests := []string {
// max.MaxFloat32
"3.40282346638528859811704183484516925440e+38",

// round up to max.MaxFloat32
"3.402823469e+38",
"3.40282346e+38",
"3.40282347e+38",
"3.40282348e+38",
"3.4028235e+38",
// TODO: fix this case
// "3.4028235677973366e+38", // Bits: 1000111111011111111111111111111111_10000000000000000000000000000

// overflow for float32, round up to max.MaxFloat32 + 1
"3.402823567797337e+38", // Bits: 1000111111011111111111111111111111_10000000000000000000000000001
"3.402823567797338e+38",
"3.4028236e+38",
}

t.Run("max float32", func(t *testing.T) {
for _, data := range(tests) {
var f1, f2 float32
se := sonic.UnmarshalString(data, &f1)
je := json.Unmarshal([]byte(data), &f2)
require.Equal(t, se != nil, je != nil, data, se, je)
require.Equal(t, f2, f1, data)
}
})

t.Run("min float32", func(t *testing.T) {
for _, data := range(tests) {
data = string("-") + data
var f1, f2 float32
se := sonic.UnmarshalString(data, &f1)
je := json.Unmarshal([]byte(data), &f2)
require.Equal(t, se != nil, je != nil, data, se, je)
require.Equal(t, f2, f1, data)
}
})
}

0 comments on commit 3ed2c48

Please sign in to comment.