util: improve isSafeAddition.
This commit is contained in:
parent
be0e7e02d2
commit
3db140e119
@ -200,14 +200,6 @@ if (Object.assign)
|
||||
|
||||
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.
|
||||
* @param {Number} value
|
||||
@ -226,9 +218,44 @@ util.isSafeInteger = function isSafeInteger(value) {
|
||||
*/
|
||||
|
||||
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(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