Skip to content

Commit b74506a

Browse files
Fix Number conversions/comparisons on big-endian systems (#103)
Fixes #98.
1 parent 9c9ff05 commit b74506a

File tree

1 file changed

+24
-8
lines changed

1 file changed

+24
-8
lines changed

lib/jsbi.ts

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,9 @@ class JSBI extends Array {
140140
}
141141
const signBit = x.sign ? (1 << 31) : 0;
142142
exponent = (exponent + 0x3FF) << 20;
143-
JSBI.__kBitConversionInts[1] = signBit | exponent | mantissaHigh;
144-
JSBI.__kBitConversionInts[0] = mantissaLow;
143+
JSBI.__kBitConversionInts[JSBI.__kBitConversionIntHigh] =
144+
signBit | exponent | mantissaHigh;
145+
JSBI.__kBitConversionInts[JSBI.__kBitConversionIntLow] = mantissaLow;
145146
return JSBI.__kBitConversionDouble[0];
146147
}
147148

@@ -654,13 +655,17 @@ class JSBI extends Array {
654655
static __fromDouble(value: number): JSBI {
655656
const sign = value < 0;
656657
JSBI.__kBitConversionDouble[0] = value;
657-
const rawExponent = (JSBI.__kBitConversionInts[1] >>> 20) & 0x7FF;
658+
const rawExponent =
659+
(JSBI.__kBitConversionInts[JSBI.__kBitConversionIntHigh] >>> 20) &
660+
0x7FF;
658661
const exponent = rawExponent - 0x3FF;
659662
const digits = ((exponent / 30) | 0) + 1;
660663
const result = new JSBI(digits, sign);
661664
const kHiddenBit = 0x00100000;
662-
let mantissaHigh = (JSBI.__kBitConversionInts[1] & 0xFFFFF) | kHiddenBit;
663-
let mantissaLow = JSBI.__kBitConversionInts[0];
665+
let mantissaHigh =
666+
(JSBI.__kBitConversionInts[JSBI.__kBitConversionIntHigh] & 0xFFFFF) |
667+
kHiddenBit;
668+
let mantissaLow = JSBI.__kBitConversionInts[JSBI.__kBitConversionIntLow];
664669
const kMantissaHighTopBit = 20;
665670
// 0-indexed position of most significant bit in most significant digit.
666671
const msdTopBit = exponent % 30;
@@ -1055,7 +1060,9 @@ class JSBI extends Array {
10551060
}
10561061
if (x.length === 0) return -1;
10571062
JSBI.__kBitConversionDouble[0] = y;
1058-
const rawExponent = (JSBI.__kBitConversionInts[1] >>> 20) & 0x7FF;
1063+
const rawExponent =
1064+
(JSBI.__kBitConversionInts[JSBI.__kBitConversionIntHigh] >>> 20) &
1065+
0x7FF;
10591066
if (rawExponent === 0x7FF) {
10601067
throw new Error('implementation bug: handled elsewhere');
10611068
}
@@ -1075,8 +1082,10 @@ class JSBI extends Array {
10751082
// Same sign, same bit length. Shift mantissa to align with x and compare
10761083
// bit for bit.
10771084
const kHiddenBit = 0x00100000;
1078-
let mantissaHigh = (JSBI.__kBitConversionInts[1] & 0xFFFFF) | kHiddenBit;
1079-
let mantissaLow = JSBI.__kBitConversionInts[0];
1085+
let mantissaHigh =
1086+
(JSBI.__kBitConversionInts[JSBI.__kBitConversionIntHigh] & 0xFFFFF) |
1087+
kHiddenBit;
1088+
let mantissaLow = JSBI.__kBitConversionInts[JSBI.__kBitConversionIntLow];
10801089
const kMantissaHighTopBit = 20;
10811090
const msdTopBit = 29 - msdLeadingZeros;
10821091
if (msdTopBit !== (((xBitLength - 1) % 30) | 0)) {
@@ -1959,6 +1968,13 @@ class JSBI extends Array {
19591968
static __kBitConversionBuffer = new ArrayBuffer(8);
19601969
static __kBitConversionDouble = new Float64Array(JSBI.__kBitConversionBuffer);
19611970
static __kBitConversionInts = new Int32Array(JSBI.__kBitConversionBuffer);
1971+
static __detectBigEndian() {
1972+
JSBI.__kBitConversionDouble[0] = -0.0;
1973+
return JSBI.__kBitConversionInts[0] !== 0;
1974+
}
1975+
static __kBitConversionIntHigh = JSBI.__detectBigEndian() ? 0 : 1;
1976+
static __kBitConversionIntLow = JSBI.__detectBigEndian() ? 1 : 0;
1977+
19621978

19631979
// For IE11 compatibility.
19641980
// Note that the custom replacements are tailored for JSBI's needs, and as

0 commit comments

Comments
 (0)