Skip to content

Commit

Permalink
Fix top digit handling in “even” case of __inplaceSub (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
jakobkummerow authored and mathiasbynens committed Nov 20, 2018
1 parent ca255a2 commit e77f163
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 13 deletions.
37 changes: 24 additions & 13 deletions jsbi.mjs
Expand Up @@ -56,7 +56,7 @@ class JSBI extends Array {
toDebugString() {
const result = ['BigInt['];
for (const digit of this) {
result.push((digit ? digit.toString(16) : digit) + ', ');
result.push((digit ? (digit >>> 0).toString(16) : digit) + ', ');
}
result.push(']');
return result.join('');
Expand Down Expand Up @@ -1454,9 +1454,9 @@ class JSBI extends Array {
}
// D4.
JSBI.__internalMultiplyAdd(divisor, qhat, 0, n2, qhatv);
let c = u.__inplaceSub(qhatv, j);
let c = u.__inplaceSub(qhatv, j, n + 1);
if (c !== 0) {
c = u.__inplaceAdd(divisor, j);
c = u.__inplaceAdd(divisor, j, n);
u.__setHalfDigit(j + n, u.__halfDigit(j + n) + c);
qhat--;
}
Expand All @@ -1483,10 +1483,9 @@ class JSBI extends Array {
}

// TODO: work on full digits, like __inplaceSub?
__inplaceAdd(summand, startIndex) {
__inplaceAdd(summand, startIndex, halfDigits) {
let carry = 0;
const n = summand.__halfDigitLength();
for (let i = 0; i < n; i++) {
for (let i = 0; i < halfDigits; i++) {
const sum = this.__halfDigit(startIndex + i) +
summand.__halfDigit(i) +
carry;
Expand All @@ -1496,7 +1495,8 @@ class JSBI extends Array {
return carry;
}

__inplaceSub(subtrahend, startIndex) {
__inplaceSub(subtrahend, startIndex, halfDigits) {
let fullSteps = (halfDigits - 1) >>> 1;
let borrow = 0;
if (startIndex & 1) {
// this: [..][..][..]
Expand All @@ -1505,7 +1505,7 @@ class JSBI extends Array {
let current = this.__digit(startIndex);
let r0 = current & 0xFFFF;
let i = 0;
for (; i < subtrahend.length - 1; i++) {
for (; i < fullSteps; i++) {
const sub = subtrahend.__digit(i);
const r16 = (current >>> 16) - (sub & 0xFFFF) - borrow;
borrow = (r16 >>> 16) & 1;
Expand All @@ -1521,18 +1521,19 @@ class JSBI extends Array {
this.__setDigit(startIndex + i, (r16 << 16) | (r0 & 0xFFFF));
const subTop = sub >>> 16;
if (startIndex + i + 1 >= this.length) {
throw new RangeError('out of bounds');
}
current = this.__digit(startIndex + i + 1);
if (subTop !== 0 || current !== 0) {
throw new RangeError('out of bounds');
}
if ((halfDigits & 1) === 0) {
current = this.__digit(startIndex + i + 1);
r0 = (current & 0xFFFF) - subTop - borrow;
borrow = (r0 >>> 16) & 1;
this.__setDigit(startIndex + subtrahend.length,
(current & 0xFFFF0000) | (r0 & 0xFFFF));
}
} else {
startIndex >>= 1;
for (let i = 0; i < subtrahend.length; i++) {
let i = 0;
for (; i < subtrahend.length - 1; i++) {
const current = this.__digit(startIndex + i);
const sub = subtrahend.__digit(i);
const r0 = (current & 0xFFFF) - (sub & 0xFFFF) - borrow;
Expand All @@ -1541,6 +1542,16 @@ throw new RangeError('out of bounds');
borrow = (r16 >>> 16) & 1;
this.__setDigit(startIndex + i, (r16 << 16) | (r0 & 0xFFFF));
}
const current = this.__digit(startIndex + i);
const sub = subtrahend.__digit(i);
const r0 = (current & 0xFFFF) - (sub & 0xFFFF) - borrow;
borrow = (r0 >>> 16) & 1;
let r16 = 0;
if ((halfDigits & 1) === 0) {
r16 = (current >>> 16) - (sub >>> 16) - borrow;
borrow = (r16 >>> 16) & 1;
}
this.__setDigit(startIndex + i, (r16 << 16) | (r0 & 0xFFFF));
}
return borrow;
}
Expand Down
12 changes: 12 additions & 0 deletions tests/tests.mjs
Expand Up @@ -30,6 +30,18 @@ const TESTS = [
b: '-0xF3CF5EDD759DBCC7449962CDB52AE0295BE7306D51555C70',
expected: '-0x1034209C3C2F251E3F2EF7068FA5CAE964C0B57661EB577E7',
},
{ // https://github.com/GoogleChromeLabs/jsbi/pull/14
operation: 'remainder',
a: '0x62A49213A5CD1793CB4518A12CA4FB5F3AB6DBD8B465D0D86975CEBDA6B6093',
b: '0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF',
expected: '0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE',
},
{ // https://github.com/GoogleChromeLabs/jsbi/pull/14#issuecomment-439484605
operation: 'remainder',
a: '0x10000000000000000',
b: '0x100000001',
expected: '0x1',
},
];

function parse(string) {
Expand Down

0 comments on commit e77f163

Please sign in to comment.