Skip to content

Commit

Permalink
Fix Number conversions/comparisons on big-endian systems
Browse files Browse the repository at this point in the history
Fixes #98.
  • Loading branch information
jakobkummerow committed Aug 14, 2023
1 parent eeead8a commit 0646c9e
Showing 1 changed file with 24 additions and 8 deletions.
32 changes: 24 additions & 8 deletions lib/jsbi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,9 @@ class JSBI extends Array {
}
const signBit = x.sign ? (1 << 31) : 0;
exponent = (exponent + 0x3FF) << 20;
JSBI.__kBitConversionInts[1] = signBit | exponent | mantissaHigh;
JSBI.__kBitConversionInts[0] = mantissaLow;
JSBI.__kBitConversionInts[JSBI.__kBitConversionIntHigh] =
signBit | exponent | mantissaHigh;
JSBI.__kBitConversionInts[JSBI.__kBitConversionIntLow] = mantissaLow;
return JSBI.__kBitConversionDouble[0];
}

Expand Down Expand Up @@ -654,13 +655,17 @@ class JSBI extends Array {
static __fromDouble(value: number): JSBI {
const sign = value < 0;
JSBI.__kBitConversionDouble[0] = value;
const rawExponent = (JSBI.__kBitConversionInts[1] >>> 20) & 0x7FF;
const rawExponent =
(JSBI.__kBitConversionInts[JSBI.__kBitConversionIntHigh] >>> 20) &
0x7FF;
const exponent = rawExponent - 0x3FF;
const digits = ((exponent / 30) | 0) + 1;
const result = new JSBI(digits, sign);
const kHiddenBit = 0x00100000;
let mantissaHigh = (JSBI.__kBitConversionInts[1] & 0xFFFFF) | kHiddenBit;
let mantissaLow = JSBI.__kBitConversionInts[0];
let mantissaHigh =
(JSBI.__kBitConversionInts[JSBI.__kBitConversionIntHigh] & 0xFFFFF) |
kHiddenBit;
let mantissaLow = JSBI.__kBitConversionInts[JSBI.__kBitConversionIntLow];
const kMantissaHighTopBit = 20;
// 0-indexed position of most significant bit in most significant digit.
const msdTopBit = exponent % 30;
Expand Down Expand Up @@ -1055,7 +1060,9 @@ class JSBI extends Array {
}
if (x.length === 0) return -1;
JSBI.__kBitConversionDouble[0] = y;
const rawExponent = (JSBI.__kBitConversionInts[1] >>> 20) & 0x7FF;
const rawExponent =
(JSBI.__kBitConversionInts[JSBI.__kBitConversionIntHigh] >>> 20) &
0x7FF;
if (rawExponent === 0x7FF) {
throw new Error('implementation bug: handled elsewhere');
}
Expand All @@ -1075,8 +1082,10 @@ class JSBI extends Array {
// Same sign, same bit length. Shift mantissa to align with x and compare
// bit for bit.
const kHiddenBit = 0x00100000;
let mantissaHigh = (JSBI.__kBitConversionInts[1] & 0xFFFFF) | kHiddenBit;
let mantissaLow = JSBI.__kBitConversionInts[0];
let mantissaHigh =
(JSBI.__kBitConversionInts[JSBI.__kBitConversionIntHigh] & 0xFFFFF) |
kHiddenBit;
let mantissaLow = JSBI.__kBitConversionInts[JSBI.__kBitConversionIntLow];
const kMantissaHighTopBit = 20;
const msdTopBit = 29 - msdLeadingZeros;
if (msdTopBit !== (((xBitLength - 1) % 30) | 0)) {
Expand Down Expand Up @@ -1959,6 +1968,13 @@ class JSBI extends Array {
static __kBitConversionBuffer = new ArrayBuffer(8);
static __kBitConversionDouble = new Float64Array(JSBI.__kBitConversionBuffer);
static __kBitConversionInts = new Int32Array(JSBI.__kBitConversionBuffer);
static __detectBigEndian() {
JSBI.__kBitConversionDouble[0] = -0.0;
return JSBI.__kBitConversionInts[0] !== 0;
}
static __kBitConversionIntHigh = JSBI.__detectBigEndian() ? 0 : 1;
static __kBitConversionIntLow = JSBI.__detectBigEndian() ? 1 : 0;


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

0 comments on commit 0646c9e

Please sign in to comment.