diff --git a/.chronus/changes/fix-negative-big-int-2024-12-06-23-51-23.md b/.chronus/changes/fix-negative-big-int-2024-12-06-23-51-23.md new file mode 100644 index 0000000000..83b6372b1c --- /dev/null +++ b/.chronus/changes/fix-negative-big-int-2024-12-06-23-51-23.md @@ -0,0 +1,7 @@ +--- +changeKind: fix +packages: + - "@typespec/compiler" +--- + +Fix incorrectly returning a positive `BigInt` for a negative `Numeric`. diff --git a/packages/compiler/src/core/numeric.ts b/packages/compiler/src/core/numeric.ts index a56b1e5db0..a9f58148c6 100644 --- a/packages/compiler/src/core/numeric.ts +++ b/packages/compiler/src/core/numeric.ts @@ -195,7 +195,12 @@ const NumericPrototype = { return equals(this[InternalDataSym], Numeric(num.toString())[InternalDataSym]) ? num : null; }, asBigInt: function (this: Numeric) { - return this.isInteger ? this[InternalDataSym].n : null; + if (!this.isInteger) { + return null; + } + + const { s, n } = this[InternalDataSym]; + return BigInt(s) * n; }, equals: function (this: Numeric, other: Numeric) { return equals(this[InternalDataSym], other[InternalDataSym]); diff --git a/packages/compiler/test/core/numeric.test.ts b/packages/compiler/test/core/numeric.test.ts index 044343daa0..f9148781a3 100644 --- a/packages/compiler/test/core/numeric.test.ts +++ b/packages/compiler/test/core/numeric.test.ts @@ -215,6 +215,7 @@ describe("asNumber", () => { ["123.456", 123.456], ["123.00", 123], ["123456789123456789123456789123456789", null], + ["-123456789123456789123456789123456789", null], ["123456789123456789.123456789123456789", null], ])("%s => %d", (a, b) => { const numeric = Numeric(a); @@ -229,6 +230,7 @@ describe("asBigInt", () => { ["123.456", null], ["123.00", 123n], ["123456789123456789123456789123456789", 123456789123456789123456789123456789n], + ["-123456789123456789123456789123456789", -123456789123456789123456789123456789n], ["123456789123456789.123456789123456789", null], ])("%s => %d", (a, b) => { const numeric = Numeric(a);