diff --git a/CHANGELOG.md b/CHANGELOG.md index 1587e0c0c5..225b60bfe5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ #### :boom: Breaking Change - Rename `JsError` to `JsExn` and error modules cleanup. https://github.com/rescript-lang/rescript/pull/7408 +- Make `BigInt.fromFloat` return an option rather than throwing an error in case it's passed a value with a decimal value. https://github.com/rescript-lang/rescript/pull/7419 #### :rocket: New Feature diff --git a/lib/es6/Stdlib_BigInt.js b/lib/es6/Stdlib_BigInt.js index 45827fdb18..6a45c334ef 100644 --- a/lib/es6/Stdlib_BigInt.js +++ b/lib/es6/Stdlib_BigInt.js @@ -1,6 +1,14 @@ +function fromFloat(value) { + try { + return BigInt(value); + } catch (exn) { + return; + } +} + function toInt(t) { return Number(t) | 0; } @@ -10,6 +18,7 @@ function bitwiseNot(x) { } export { + fromFloat, toInt, bitwiseNot, } diff --git a/lib/js/Stdlib_BigInt.js b/lib/js/Stdlib_BigInt.js index f4dad6af37..88012bc1b6 100644 --- a/lib/js/Stdlib_BigInt.js +++ b/lib/js/Stdlib_BigInt.js @@ -1,6 +1,14 @@ 'use strict'; +function fromFloat(value) { + try { + return BigInt(value); + } catch (exn) { + return; + } +} + function toInt(t) { return Number(t) | 0; } @@ -9,6 +17,7 @@ function bitwiseNot(x) { return x ^ -1n; } +exports.fromFloat = fromFloat; exports.toInt = toInt; exports.bitwiseNot = bitwiseNot; /* No side effect */ diff --git a/runtime/Stdlib_BigInt.res b/runtime/Stdlib_BigInt.res index db860210dd..6ba756aa4e 100644 --- a/runtime/Stdlib_BigInt.res +++ b/runtime/Stdlib_BigInt.res @@ -37,6 +37,12 @@ external fromStringExn: string => bigint = "BigInt" @val external fromInt: int => bigint = "BigInt" @val external fromFloat: float => bigint = "BigInt" +let fromFloat = (value: float) => { + try Some(fromFloat(value)) catch { + | _ => None + } +} + @send /** Formats a `bigint` as a string. Return a `string` representing the given value. diff --git a/tests/tests/src/core/Core_TempTests.mjs b/tests/tests/src/core/Core_TempTests.mjs index 7b189a747f..b2e214b011 100644 --- a/tests/tests/src/core/Core_TempTests.mjs +++ b/tests/tests/src/core/Core_TempTests.mjs @@ -140,7 +140,7 @@ console.info("BigInt"); console.info("---"); -console.log(Primitive_bigint.div(BigInt(1), BigInt(12.0))); +console.log(Primitive_bigint.div(BigInt(1), Stdlib_Option.getOr(Stdlib_BigInt.fromFloat(12.0), 0n))); console.info(""); diff --git a/tests/tests/src/core/Core_TempTests.res b/tests/tests/src/core/Core_TempTests.res index a3fe866caa..982ea21f73 100644 --- a/tests/tests/src/core/Core_TempTests.res +++ b/tests/tests/src/core/Core_TempTests.res @@ -77,7 +77,7 @@ Console.info("---") @warning("-44") Console.log({ open BigInt - fromInt(1) / fromFloat(12.0) + fromInt(1) / fromFloat(12.0)->Option.getOr(0n) }) Console.info("") diff --git a/tests/tests/src/core/Core_TestTests.mjs b/tests/tests/src/core/Core_TestTests.mjs index f39a4dce04..df93ae7d4c 100644 --- a/tests/tests/src/core/Core_TestTests.mjs +++ b/tests/tests/src/core/Core_TestTests.mjs @@ -2,11 +2,13 @@ import * as Test from "./Test.mjs"; import * as Pervasives from "rescript/lib/es6/Pervasives.js"; +import * as Stdlib_BigInt from "rescript/lib/es6/Stdlib_BigInt.js"; +import * as Stdlib_Option from "rescript/lib/es6/Stdlib_Option.js"; import * as Primitive_object from "rescript/lib/es6/Primitive_object.js"; let eq = Primitive_object.equal; -let bign = BigInt(Number.MAX_VALUE); +let bign = Stdlib_Option.getOr(Stdlib_BigInt.fromFloat(Number.MAX_VALUE), 0n); let bign$1 = bign + bign; diff --git a/tests/tests/src/core/Core_TestTests.res b/tests/tests/src/core/Core_TestTests.res index f2f0dcad99..1bf71d566a 100644 --- a/tests/tests/src/core/Core_TestTests.res +++ b/tests/tests/src/core/Core_TestTests.res @@ -1,6 +1,6 @@ let eq = (a, b) => a == b -let bign = BigInt.fromFloat(Float.Constants.maxValue) +let bign = BigInt.fromFloat(Float.Constants.maxValue)->Option.getOr(0n) let bign = BigInt.add(bign, bign) Test.run(__POS_OF__("print null"), Test.print(null), eq, "null")