Patch formatjs BigDecimal to stop dividing by 1 on every number format (#11610)

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Tomasz Zawadzki
2026-08-31 14:26:13 +02:00
committed by GitHub
parent 4b4f5f9c9a
commit 67375fe2cd
3 changed files with 35 additions and 3 deletions
+30
View File
@@ -0,0 +1,30 @@
diff --git a/index.js b/index.js
index 12101e1b954e1a8c7bf7887bef4f4e08fb06a8be..51d7af352a8a222c5320426f376d51c5a173300b 100644
--- a/index.js
+++ b/index.js
@@ -170,6 +170,13 @@ var BigDecimal = class BigDecimal {
times(y) {
const other = BigDecimal._coerce(y);
if (this._special || other._special) return this._specialArith(other, "times");
+ // Fast path: multiplying by exactly 1 is an identity operation. ECMA-402's
+ // ToRawFixed multiplies by roundingIncrement, which defaults to 1, on every
+ // format call - without this check that is a full BigInt multiply followed
+ // by a trailing-zero strip. BigDecimal is immutable, so returning the
+ // existing instance is safe.
+ if (other._mantissa === 1n && other._exponent === 0) return this;
+ if (this._mantissa === 1n && this._exponent === 0) return other;
if (this._mantissa === 0n || other._mantissa === 0n) {
const negZero = this._isSignNegative() ? !other._isSignNegative() : other._isSignNegative();
return BigDecimal._create(0n, 0, SpecialValue.NONE, negZero);
@@ -189,6 +196,11 @@ var BigDecimal = class BigDecimal {
const negZero = this._isSignNegative() !== other._isSignNegative();
return BigDecimal._create(0n, 0, SpecialValue.NONE, negZero);
}
+ // Fast path: dividing by exactly 1 is an identity operation. ECMA-402's
+ // ToRawFixed divides by roundingIncrement, which defaults to 1, on every
+ // format call - without this check that is a 10^DIV_PRECISION BigInt
+ // scale-up, a division, and a trailing-zero strip that undoes the scaling.
+ if (other._mantissa === 1n && other._exponent === 0) return this;
const [nm, ne] = removeTrailingZeros(this._mantissa * bigintPow10(DIV_PRECISION) / other._mantissa, this._exponent - other._exponent - DIV_PRECISION);
return BigDecimal._create(nm, ne, SpecialValue.NONE, false);
}
+4 -3
View File
@@ -217,6 +217,7 @@ overrides:
packageExtensionsChecksum: sha256-KbeCj471Qk3TA758q8nLPkiGCPDA0TX18iO/Coy89lo=
patchedDependencies:
'@formatjs/bigdecimal@0.2.5': 53afe18a845c1469b8b9002a460582559dfd52f502bc66a0f4c05662c2619291
'@sentry/expo-upload-sourcemaps@8.18.0': 2368e1e1986165e7ead3c60017b78b2f9ade1b6a6b2f5ad27cd428608c6f12ae
expo-age-range@57.0.2: c325225749993424461eeece1d97a99b19c00da2ebc958a73c12e4eca0c39306
expo-haptics@57.0.1: b33910ba2753c4eccdc885b449e6e33aa90b9cefa75ca8639762a26013141410
@@ -11345,7 +11346,7 @@ snapshots:
'@floating-ui/utils@0.2.11': {}
'@formatjs/bigdecimal@0.2.5': {}
'@formatjs/bigdecimal@0.2.5(patch_hash=53afe18a845c1469b8b9002a460582559dfd52f502bc66a0f4c05662c2619291)': {}
'@formatjs/fast-memoize@3.1.5': {}
@@ -11366,12 +11367,12 @@ snapshots:
'@formatjs/intl-numberformat@9.3.10':
dependencies:
'@formatjs/bigdecimal': 0.2.5
'@formatjs/bigdecimal': 0.2.5(patch_hash=53afe18a845c1469b8b9002a460582559dfd52f502bc66a0f4c05662c2619291)
'@formatjs/intl-localematcher': 0.8.9
'@formatjs/intl-pluralrules@6.3.9':
dependencies:
'@formatjs/bigdecimal': 0.2.5
'@formatjs/bigdecimal': 0.2.5(patch_hash=53afe18a845c1469b8b9002a460582559dfd52f502bc66a0f4c05662c2619291)
'@formatjs/intl-localematcher': 0.8.9
'@formatjs/intl-supportedvaluesof@2.3.7':
+1
View File
@@ -29,6 +29,7 @@ allowBuilds:
'esbuild': false
'unrs-resolver': true
patchedDependencies:
'@formatjs/bigdecimal@0.2.5': patches/@formatjs__bigdecimal@0.2.5.patch
'@sentry/expo-upload-sourcemaps@8.18.0': patches/@sentry__expo-upload-sourcemaps@8.18.0.patch
'expo-age-range@57.0.2': patches/expo-age-range@57.0.2.patch
'expo-haptics@57.0.1': patches/expo-haptics@57.0.1.patch