From 8e943c666fccf0e00f570f6c7239e0f3872e4895 Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Mon, 2 Oct 2023 15:17:08 +0200 Subject: [PATCH 1/5] 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) +} From 019c00e827d77eaccd295b671ef8006ebbb3e661 Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Wed, 4 Oct 2023 14:38:57 +0200 Subject: [PATCH 2/5] Change test to use constants and remove panic Signed-off-by: Antonio Navarro Perez --- gnovm/pkg/gnolang/values_conversions.go | 4 +--- .../tests/testdata/TestMemPackage/success/float_test.gno | 9 ++++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/gnovm/pkg/gnolang/values_conversions.go b/gnovm/pkg/gnolang/values_conversions.go index 2e6a6c9d792..88caec169ac 100644 --- a/gnovm/pkg/gnolang/values_conversions.go +++ b/gnovm/pkg/gnolang/values_conversions.go @@ -1261,9 +1261,7 @@ func ConvertUntypedBigdecTo(dst *TypedValue, bv BigdecValue, t Type) { 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) { + if math.IsInf(f64, 0) { panic("cannot convert untyped bigdec to float64 -- too close to +-Inf") } dst.SetFloat64(f64) diff --git a/gnovm/tests/testdata/TestMemPackage/success/float_test.gno b/gnovm/tests/testdata/TestMemPackage/success/float_test.gno index ea7a5b54c9b..ebcbc67435d 100644 --- a/gnovm/tests/testdata/TestMemPackage/success/float_test.gno +++ b/gnovm/tests/testdata/TestMemPackage/success/float_test.gno @@ -2,9 +2,12 @@ package test import "testing" -func TestSmallestFloat(t *testing.T) { - SmallestNonzeroFloat64 := 0x1p-1022 * 0x1p-52 // 4.9406564584124654417656879286822137236505980e-324 - DividedByTwo := SmallestNonzeroFloat64 / 2 +const ( + SmallestNonzeroFloat64 = 0x1p-1022 * 0x1p-52 // 4.9406564584124654417656879286822137236505980e-324 + DividedByTwo = SmallestNonzeroFloat64 / 2 +) + +func TestSmallestFloat(t *testing.T) { println(DividedByTwo) } From a95439d561382eba08165700832205841ff7a7c1 Mon Sep 17 00:00:00 2001 From: Morgan Bazalgette Date: Fri, 13 Oct 2023 00:31:42 +0100 Subject: [PATCH 3/5] move tests --- gnovm/tests/files/float6.gno | 15 +++++++++++++++ gnovm/tests/machine_test.go | 5 ----- .../TestMemPackage/success/float_test.gno | 13 ------------- 3 files changed, 15 insertions(+), 18 deletions(-) create mode 100644 gnovm/tests/files/float6.gno delete mode 100644 gnovm/tests/testdata/TestMemPackage/success/float_test.gno diff --git a/gnovm/tests/files/float6.gno b/gnovm/tests/files/float6.gno new file mode 100644 index 00000000000..fde79006810 --- /dev/null +++ b/gnovm/tests/files/float6.gno @@ -0,0 +1,15 @@ +package test + +import "testing" + +const ( + SmallestNonzeroFloat64 = 0x1p-1022 * 0x1p-52 // 4.9406564584124654417656879286822137236505980e-324 + DividedByTwo = SmallestNonzeroFloat64 / 2 +) + +func main() { + println(DividedByTwo) +} + +// Output: +// 0 diff --git a/gnovm/tests/machine_test.go b/gnovm/tests/machine_test.go index c5132d24e19..a67d67f1ff2 100644 --- a/gnovm/tests/machine_test.go +++ b/gnovm/tests/machine_test.go @@ -23,11 +23,6 @@ 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 deleted file mode 100644 index ebcbc67435d..00000000000 --- a/gnovm/tests/testdata/TestMemPackage/success/float_test.gno +++ /dev/null @@ -1,13 +0,0 @@ -package test - -import "testing" - -const ( - SmallestNonzeroFloat64 = 0x1p-1022 * 0x1p-52 // 4.9406564584124654417656879286822137236505980e-324 - DividedByTwo = SmallestNonzeroFloat64 / 2 -) - - -func TestSmallestFloat(t *testing.T) { - println(DividedByTwo) -} From 94623619704e5628c9dac33ad5b2ee3847806961 Mon Sep 17 00:00:00 2001 From: Morgan Bazalgette Date: Fri, 13 Oct 2023 00:39:29 +0100 Subject: [PATCH 4/5] fix conversions for float32 too --- gnovm/pkg/gnolang/values_conversions.go | 6 ++---- gnovm/tests/files/float6.gno | 2 +- gnovm/tests/files/float7.gno | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 gnovm/tests/files/float7.gno diff --git a/gnovm/pkg/gnolang/values_conversions.go b/gnovm/pkg/gnolang/values_conversions.go index 88caec169ac..cc7c0de9f09 100644 --- a/gnovm/pkg/gnolang/values_conversions.go +++ b/gnovm/pkg/gnolang/values_conversions.go @@ -1246,10 +1246,8 @@ func ConvertUntypedBigdecTo(dst *TypedValue, bv BigdecValue, t Type) { } bf := big.NewFloat(f64) - f32, acc := bf.Float32() - if f32 == 0 && (acc == big.Below || acc == big.Above) { - panic("cannot convert untyped bigdec to float32 -- too close to zero") - } else if math.IsInf(float64(f32), 0) { + f32, _ := bf.Float32() + if math.IsInf(float64(f32), 0) { panic("cannot convert untyped bigdec to float32 -- too close to +-Inf") } dst.SetFloat32(f32) diff --git a/gnovm/tests/files/float6.gno b/gnovm/tests/files/float6.gno index fde79006810..8a9337af588 100644 --- a/gnovm/tests/files/float6.gno +++ b/gnovm/tests/files/float6.gno @@ -1,4 +1,4 @@ -package test +package main import "testing" diff --git a/gnovm/tests/files/float7.gno b/gnovm/tests/files/float7.gno new file mode 100644 index 00000000000..767de3671f8 --- /dev/null +++ b/gnovm/tests/files/float7.gno @@ -0,0 +1,17 @@ +package main + +import "testing" + +const ( + SmallestNonzeroFloat32 = 0x1p-126 * 0x1p-23 // 1.401298464324817070923729583289916131280e-45 + DividedByTwo = SmallestNonzeroFloat32 / 2 +) + +func main() { + var i float32 + i = DividedByTwo + println(i) +} + +// Output: +// 0 From ad43409ac7d7e800519a6a75e767f7d43212d668 Mon Sep 17 00:00:00 2001 From: Morgan Bazalgette Date: Fri, 13 Oct 2023 00:59:20 +0100 Subject: [PATCH 5/5] remove testing import --- gnovm/tests/files/float6.gno | 2 -- gnovm/tests/files/float7.gno | 2 -- 2 files changed, 4 deletions(-) diff --git a/gnovm/tests/files/float6.gno b/gnovm/tests/files/float6.gno index 8a9337af588..680b9461975 100644 --- a/gnovm/tests/files/float6.gno +++ b/gnovm/tests/files/float6.gno @@ -1,7 +1,5 @@ package main -import "testing" - const ( SmallestNonzeroFloat64 = 0x1p-1022 * 0x1p-52 // 4.9406564584124654417656879286822137236505980e-324 DividedByTwo = SmallestNonzeroFloat64 / 2 diff --git a/gnovm/tests/files/float7.gno b/gnovm/tests/files/float7.gno index 767de3671f8..f519a963523 100644 --- a/gnovm/tests/files/float7.gno +++ b/gnovm/tests/files/float7.gno @@ -1,7 +1,5 @@ package main -import "testing" - const ( SmallestNonzeroFloat32 = 0x1p-126 * 0x1p-23 // 1.401298464324817070923729583289916131280e-45 DividedByTwo = SmallestNonzeroFloat32 / 2