util: improve isSafeAddition.
This commit is contained in:
parent
be0e7e02d2
commit
3db140e119
@ -200,14 +200,6 @@ if (Object.assign)
|
|||||||
|
|
||||||
util.MAX_SAFE_INTEGER = 0x1fffffffffffff;
|
util.MAX_SAFE_INTEGER = 0x1fffffffffffff;
|
||||||
|
|
||||||
/**
|
|
||||||
* Max safe addition (52 bits).
|
|
||||||
* @const {Number}
|
|
||||||
* @default
|
|
||||||
*/
|
|
||||||
|
|
||||||
util.MAX_SAFE_ADDITION = 0xfffffffffffff;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test whether a number is below MAX_SAFE_INTEGER.
|
* Test whether a number is below MAX_SAFE_INTEGER.
|
||||||
* @param {Number} value
|
* @param {Number} value
|
||||||
@ -226,9 +218,44 @@ util.isSafeInteger = function isSafeInteger(value) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
util.isSafeAddition = function isSafeAddition(a, b) {
|
util.isSafeAddition = function isSafeAddition(a, b) {
|
||||||
|
var hi, lo, ahi, alo, bhi, blo;
|
||||||
|
var as, bs, s, c;
|
||||||
|
|
||||||
|
// We only work on positive numbers.
|
||||||
assert(a >= 0);
|
assert(a >= 0);
|
||||||
assert(b >= 0);
|
assert(b >= 0);
|
||||||
return a <= util.MAX_SAFE_ADDITION && b <= util.MAX_SAFE_ADDITION;
|
|
||||||
|
// Fast case.
|
||||||
|
if (a <= 0xfffffffffffff && b <= 0xfffffffffffff)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Do a 64 bit addition and check the top 11 bits.
|
||||||
|
ahi = (a * (1 / 0x100000000)) | 0;
|
||||||
|
alo = a | 0;
|
||||||
|
|
||||||
|
bhi = (b * (1 / 0x100000000)) | 0;
|
||||||
|
blo = b | 0;
|
||||||
|
|
||||||
|
// Credit to @indutny for this method.
|
||||||
|
lo = (alo + blo) | 0;
|
||||||
|
|
||||||
|
s = lo >> 31;
|
||||||
|
as = alo >> 31;
|
||||||
|
bs = blo >> 31;
|
||||||
|
|
||||||
|
c = ((as & bs) | (~s & (as ^ bs))) & 1;
|
||||||
|
|
||||||
|
hi = (((ahi + bhi) | 0) + c) | 0;
|
||||||
|
|
||||||
|
hi >>>= 0;
|
||||||
|
ahi >>>= 0;
|
||||||
|
bhi >>>= 0;
|
||||||
|
|
||||||
|
// Overflow?
|
||||||
|
if (hi < ahi || hi < bhi)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return (hi & 0xffe00000) === 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user