Skip to content

Commit

Permalink
Use integer comparison for equality
Browse files Browse the repository at this point in the history
If we are comparing 2 numbers that are even integers, compare them via
big.Int values rather than formatted strings. This avoids problems with
large integers stored in big.Float with different precisions which could
format differently.
  • Loading branch information
jbardin authored and apparentlymart committed Jan 30, 2024
1 parent 1348b69 commit a0315a5
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 1 deletion.
16 changes: 15 additions & 1 deletion cty/primitive_type.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package cty

import "math/big"
import (
"math/big"
)

// primitiveType is the hidden implementation of the various primitive types
// that are exposed as variables in this package.
Expand Down Expand Up @@ -77,6 +79,18 @@ func rawNumberEqual(a, b *big.Float) bool {
case a.Sign() != b.Sign():
return false
default:
// First check if these are integers, and compare them directly. Floats
// need a more nuanced approach.
aInt, aAcc := a.Int(nil)
bInt, bAcc := b.Int(nil)
if aAcc != bAcc {
// only one is an exact integer value, so they can't be equal
return false
}
if aAcc == big.Exact {
return aInt.Cmp(bInt) == 0
}

// This format and precision matches that used by cty/json.Marshal,
// and thus achieves our definition of "two numbers are equal if
// we'd use the same JSON serialization for both of them".
Expand Down
5 changes: 5 additions & 0 deletions cty/value_ops_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ func TestValueEquals(t *testing.T) {
NumberFloatVal(1.22222),
BoolVal(true),
},
{
MustParseNumberVal("9223372036854775808"),
NumberFloatVal(float64(9223372036854775808)),
BoolVal(true),
},

// Strings
{
Expand Down

0 comments on commit a0315a5

Please sign in to comment.