diff --git a/src/Fable.Cli/CHANGELOG.md b/src/Fable.Cli/CHANGELOG.md index 23d5047e95..fd33543ab1 100644 --- a/src/Fable.Cli/CHANGELOG.md +++ b/src/Fable.Cli/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Fixed + +* [JS/TS] Fixed BigInt.ToDecimal with negative values (#3500) (by @ncave) + ## 4.19.1 - 2024-06-13 ### Fixed diff --git a/src/fable-library-ts/BigInt.ts b/src/fable-library-ts/BigInt.ts index e2acfe7b4d..a0c5f0aec6 100644 --- a/src/fable-library-ts/BigInt.ts +++ b/src/fable-library-ts/BigInt.ts @@ -148,10 +148,11 @@ export function toFloat32(x: bigint): float32 { return Number(x); } export function toFloat64(x: bigint): float64 { return Number(x); } export function toDecimal(x: bigint): decimal { - const low = Number(BigInt.asUintN(32, x)) - const mid = Number(BigInt.asUintN(32, x >> 32n)) - const high = Number(BigInt.asUintN(32, x >> 64n)) const isNegative = x < zero; + const bits = abs(x); + const low = Number(BigInt.asUintN(32, bits)); + const mid = Number(BigInt.asUintN(32, bits >> 32n)); + const high = Number(BigInt.asUintN(32, bits >> 64n)); const scale = 0; return fromParts(low, mid, high, isNegative, scale) } diff --git a/tests/Js/Main/ConvertTests.fs b/tests/Js/Main/ConvertTests.fs index e9f966d2c9..027b88bd03 100644 --- a/tests/Js/Main/ConvertTests.fs +++ b/tests/Js/Main/ConvertTests.fs @@ -1090,6 +1090,14 @@ let tests = let value = 1.0m decimal (bigint value) |> equal value + testCase "BigInt ToDecimal with Decimal.MinValue works" <| fun () -> + let value = Decimal.MinValue + decimal (bigint value) |> equal value + + testCase "BigInt ToDecimal with Decimal.MaxValue works" <| fun () -> + let value = Decimal.MaxValue + decimal (bigint value) |> equal value + testCase "BigInt ToString works" <| fun () -> let value = 1234567890 string (bigint value) |> equal "1234567890" diff --git a/tests/Python/TestConvert.fs b/tests/Python/TestConvert.fs index 5d57610232..cea85cf143 100644 --- a/tests/Python/TestConvert.fs +++ b/tests/Python/TestConvert.fs @@ -1188,6 +1188,16 @@ let ``test BigInt ToDecimal works`` () = let value = 1.0m decimal (bigint value) |> equal value +[] +let ``test BigInt ToDecimal with Decimal.MinValue works`` () = + let value = Decimal.MinValue + decimal (bigint value) |> equal value + +[] +let ``test BigInt ToDecimal with Decimal.MaxValue works`` () = + let value = Decimal.MaxValue + decimal (bigint value) |> equal value + [] let ``test BigInt ToString works`` () = let value = 1234567890 diff --git a/tests/Rust/tests/src/ConvertTests.fs b/tests/Rust/tests/src/ConvertTests.fs index bfa40f5a4c..184c2714e2 100644 --- a/tests/Rust/tests/src/ConvertTests.fs +++ b/tests/Rust/tests/src/ConvertTests.fs @@ -1257,6 +1257,16 @@ let ``BigInt ToDecimal works`` () = let value = 1.0m decimal (bigint value) |> equal value +[] +let ``BigInt ToDecimal with Decimal.MinValue works`` () = + let value = Decimal.MinValue + decimal (bigint value) |> equal value + +[] +let ``BigInt ToDecimal with Decimal.MaxValue works`` () = + let value = Decimal.MaxValue + decimal (bigint value) |> equal value + [] let ``BigInt ToString works`` () = let value = 1234567890