From 8557a308f1126217f2a87a610a4ceda5a31b09e3 Mon Sep 17 00:00:00 2001 From: Gabor Greif Date: Thu, 26 Sep 2024 19:15:21 +0300 Subject: [PATCH] fix: reproduce and fix `motoko-base/issues/653` (#4712) Cf. fixes dfinity/motoko-base#653 It appears that `a <> Big_int.zero_big_int` blows up when `a` is zero. Weird. Eliminating the comparison doesn't hurt correctness, and is probably more efficient too, as negating zero should be cheap! @timohanke feel free to review too! --- src/mo_values/numerics.ml | 6 +++--- test/run/issue-base653.mo | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 test/run/issue-base653.mo diff --git a/src/mo_values/numerics.ml b/src/mo_values/numerics.ml index cd540fe3db0..45ae04ced67 100644 --- a/src/mo_values/numerics.ml +++ b/src/mo_values/numerics.ml @@ -41,7 +41,7 @@ let bigint_of_double (f : Wasm.F64.t) : Big_int.big_int = (* Fraction part of IEEE 754 double, 52 bits from the float, with an implicit 1 at the 53rd bit *) - let frac = Int64.(logor (shift_right_logical (shift_left bits 12) 12) (shift_left (of_int 1) 52)) in + let frac = Int64.(logor (shift_right_logical (shift_left bits 12) 12) (shift_left one 52)) in if Int64.(equal exp bits_11) then (* Exponent is fully set: NaN or inf *) @@ -55,7 +55,7 @@ let bigint_of_double (f : Wasm.F64.t) : Big_int.big_int = let a = Big_int.big_int_of_int64 frac in - let a = if Int64.(compare exp (of_int 0)) < 0 then + let a = if Int64.(compare exp zero) < 0 then (* Exponent < 0, shift right *) Big_int.(shift_right_big_int a (- (Int64.to_int exp))) else @@ -64,7 +64,7 @@ let bigint_of_double (f : Wasm.F64.t) : Big_int.big_int = in (* Negate the number if sign bit is set (double is negative) *) - if Int64.shift_right_logical bits 63 = Int64.of_int 1 && a <> Big_int.zero_big_int then + if Int64.(shift_right_logical bits 63 = one) then Big_int.minus_big_int a else a diff --git a/test/run/issue-base653.mo b/test/run/issue-base653.mo new file mode 100644 index 00000000000..0f15a0d9c25 --- /dev/null +++ b/test/run/issue-base653.mo @@ -0,0 +1,4 @@ +import { floatCopySign; floatToInt64 } = "mo:⛔"; + +assert 0 == floatToInt64(-0.5); +assert 0 == floatToInt64(floatCopySign(0.0, -1.0));