Skip to content

Commit

Permalink
util: fix codec for negative zero (#57343)
Browse files Browse the repository at this point in the history
close #41878
  • Loading branch information
wshwsh12 authored Nov 15, 2024
1 parent 4fded5f commit 9b26569
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 1 deletion.
19 changes: 19 additions & 0 deletions pkg/util/codec/codec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1333,3 +1333,22 @@ func TestDatumHashEquals(t *testing.T) {
require.NotEqual(t, hasher1.Sum64(), hasher2.Sum64())
require.False(t, tests[len(tests)-1].d1.Equals(tests[len(tests)-1].d2))
}

func TestEncodeFloatForNegativeZero(t *testing.T) {
floatNum := 0.0
floatNum = -floatNum

b := EncodeFloat(nil, floatNum)
_, v, err := DecodeFloat(b)
require.NoError(t, err)
require.Equal(t, floatNum, v)
require.Equal(t, math.Signbit(floatNum), math.Signbit(v))
require.Equal(t, math.Atan2(0, v), math.Pi)

b = EncodeFloatDesc(nil, floatNum)
_, v, err = DecodeFloatDesc(b)
require.NoError(t, err)
require.Equal(t, floatNum, v)
require.Equal(t, math.Signbit(floatNum), math.Signbit(v))
require.Equal(t, math.Atan2(0, v), math.Pi)
}
10 changes: 9 additions & 1 deletion pkg/util/codec/float.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,17 @@ import (

func encodeFloatToCmpUint64(f float64) uint64 {
u := math.Float64bits(f)
if f >= 0 {
// Check the sign bit (the highest bit in the IEEE 754 representation).
// If the sign bit is 0, the number is non-negative (+0 is considered non-negative).
if u&signMask == 0 {
// For non-negative numbers (+0 included), set the sign bit to 1.
// This ensures non-negative numbers are ordered after negative numbers
// when compared as unsigned integers.
u |= signMask
} else {
// For negative numbers (-0 included), invert all bits.
// This reorders negative numbers so that the smallest (closest to 0)
// has the smallest encoded value, and the most negative has the largest.
u = ^u
}
return u
Expand Down
6 changes: 6 additions & 0 deletions tests/integrationtest/r/expression/issues.result
Original file line number Diff line number Diff line change
Expand Up @@ -3230,3 +3230,9 @@ INSERT INTO test.t VALUES (1234567890123456);
SELECT IFNULL(id, 'abcdef') FROM test.t;
IFNULL(id, 'abcdef')
1234567890123456
DROP TABLE IF EXISTS test.t;
CREATE TABLE test.t (c0 decimal(10,0));
INSERT INTO test.t VALUES (0);
SELECT c0 FROM test.t WHERE CAST(ATAN2(((t.c0) IS NULL), (- (''))) AS TIME);
c0
0
6 changes: 6 additions & 0 deletions tests/integrationtest/t/expression/issues.test
Original file line number Diff line number Diff line change
Expand Up @@ -2182,3 +2182,9 @@ DROP TABLE IF EXISTS test.t;
CREATE TABLE test.t (id bigint(11) UNSIGNED PRIMARY KEY);
INSERT INTO test.t VALUES (1234567890123456);
SELECT IFNULL(id, 'abcdef') FROM test.t;

# TestIssue41878
DROP TABLE IF EXISTS test.t;
CREATE TABLE test.t (c0 decimal(10,0));
INSERT INTO test.t VALUES (0);
SELECT c0 FROM test.t WHERE CAST(ATAN2(((t.c0) IS NULL), (- (''))) AS TIME);

0 comments on commit 9b26569

Please # to comment.