From 104d9a29ec3430bea8317029e7750c123f7e5207 Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Mon, 2 Oct 2023 15:17:08 +0200 Subject: [PATCH] fix: test smallest float divided by zero Signed-off-by: Antonio Navarro Perez --- gnovm/pkg/gnolang/values_conversions.go | 11 ++++++-- gnovm/pkg/gnolang/values_conversions_test.go | 25 +++++++++++++++++++ gnovm/tests/machine_test.go | 5 ++++ .../TestMemPackage/success/float_test.gno | 10 ++++++++ 4 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 gnovm/pkg/gnolang/values_conversions_test.go create mode 100644 gnovm/tests/testdata/TestMemPackage/success/float_test.gno diff --git a/gnovm/pkg/gnolang/values_conversions.go b/gnovm/pkg/gnolang/values_conversions.go index 9fc2ce4a567..2e6a6c9d792 100644 --- a/gnovm/pkg/gnolang/values_conversions.go +++ b/gnovm/pkg/gnolang/values_conversions.go @@ -1240,7 +1240,11 @@ func ConvertUntypedBigdecTo(dst *TypedValue, bv BigdecValue, t Type) { case Float32Kind: dst.T = t dst.V = nil - f64, _ := bd.Float64() + f64, err := bd.Float64() + if err != nil { + panic(fmt.Errorf("cannot convert untyped bigdec to float64: %w", err)) + } + bf := big.NewFloat(f64) f32, acc := bf.Float32() if f32 == 0 && (acc == big.Below || acc == big.Above) { @@ -1253,7 +1257,10 @@ func ConvertUntypedBigdecTo(dst *TypedValue, bv BigdecValue, t Type) { case Float64Kind: dst.T = t dst.V = nil - f64, _ := bd.Float64() + f64, err := bd.Float64() + if err != nil { + panic(fmt.Errorf("cannot convert untyped bigdec to float64: %w", err)) + } if f64 == 0 && !bd.IsZero() { panic("cannot convert untyped bigdec to float64 -- too close to zero") } else if math.IsInf(f64, 0) { diff --git a/gnovm/pkg/gnolang/values_conversions_test.go b/gnovm/pkg/gnolang/values_conversions_test.go new file mode 100644 index 00000000000..b9ac9e68d68 --- /dev/null +++ b/gnovm/pkg/gnolang/values_conversions_test.go @@ -0,0 +1,25 @@ +package gnolang + +import ( + "math" + "testing" + + "github.com/cockroachdb/apd" + "github.com/stretchr/testify/require" +) + +func TestConvertUntypedBigdecToFloat(t *testing.T) { + dst := &TypedValue{} + + dec, err := apd.New(-math.MaxInt64, -4).SetFloat64(math.SmallestNonzeroFloat64 / 2) + require.NoError(t, err) + bd := BigdecValue{ + V: dec, + } + + typ := Float64Type + + ConvertUntypedBigdecTo(dst, bd, typ) + + require.Equal(t, float64(0), dst.GetFloat64()) +} diff --git a/gnovm/tests/machine_test.go b/gnovm/tests/machine_test.go index a67d67f1ff2..c5132d24e19 100644 --- a/gnovm/tests/machine_test.go +++ b/gnovm/tests/machine_test.go @@ -23,6 +23,11 @@ func TestMachineTestMemPackage(t *testing.T) { path: "testdata/TestMemPackage/success", shouldSucceed: true, }, + { + name: "TestSmallestFloat", + path: "testdata/TestMemPackage/success", + shouldSucceed: true, + }, { name: "TestFail", path: "testdata/TestMemPackage/fail", diff --git a/gnovm/tests/testdata/TestMemPackage/success/float_test.gno b/gnovm/tests/testdata/TestMemPackage/success/float_test.gno new file mode 100644 index 00000000000..ea7a5b54c9b --- /dev/null +++ b/gnovm/tests/testdata/TestMemPackage/success/float_test.gno @@ -0,0 +1,10 @@ +package test + +import "testing" + +func TestSmallestFloat(t *testing.T) { + SmallestNonzeroFloat64 := 0x1p-1022 * 0x1p-52 // 4.9406564584124654417656879286822137236505980e-324 + DividedByTwo := SmallestNonzeroFloat64 / 2 + + println(DividedByTwo) +}