Skip to content

Commit

Permalink
Add isSafeInteger to test if a Long can be safely represented as a JS…
Browse files Browse the repository at this point in the history
… number
  • Loading branch information
dcodeIO committed Feb 10, 2025
1 parent 167d391 commit 2eb79a4
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 0 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,9 @@ API
* Long#**isPositive**(): `boolean`<br />
Tests if this Long's value is positive or zero.

* Long#**isSafeInteger**(): `boolean`<br />
Tests if this Long can be safely represented as a JavaScript number.

* Long#**isZero**/**eqz**(): `boolean`<br />
Tests if this Long's value equals zero.

Expand Down
16 changes: 16 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,22 @@ LongPrototype.getNumBitsAbs = function getNumBitsAbs() {
return this.high != 0 ? bit + 33 : bit + 1;
};

/**
* Tests if this Long can be safely represented as a JavaScript number.
* @this {!Long}
* @returns {boolean}
*/
LongPrototype.isSafeInteger = function isSafeInteger() {
// 2^53-1 is the maximum safe value
var top11Bits = this.high >> 21;
// [0, 2^53-1]
if (!top11Bits) return true;
// > 2^53-1
if (this.unsigned) return false;
// [-2^53, -1] except -2^53
return top11Bits === -1 && !(this.low === 0 && this.high === -0x200000);
};

/**
* Tests if this Long's value equals zero.
* @this {!Long}
Expand Down
13 changes: 13 additions & 0 deletions tests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,19 @@ var tests = [ // BEGIN TEST CASES
var signedFromUnsigned = Long.fromBigInt(values[i].unsigned);
assert.strictEqual(signedFromUnsigned.toBigInt(), values[i].signed);
}
},

function testSafeInteger() {
assert(Long.fromNumber(0).isSafeInteger());
assert(Long.fromNumber(1).isSafeInteger());
assert(Long.fromNumber(-1).isSafeInteger());
assert(!Long.fromNumber(-1).toUnsigned().isSafeInteger());
assert(Long.fromNumber(Math.pow(2, 32)).isSafeInteger());
assert(Long.fromNumber(-Math.pow(2, 32)).isSafeInteger());
assert(Long.fromNumber(Math.pow(2, 53) - 1).isSafeInteger());
assert(Long.fromNumber(-Math.pow(2, 53) + 1).isSafeInteger());
assert(!Long.fromNumber(Math.pow(2, 53)).isSafeInteger());
assert(!Long.fromNumber(-Math.pow(2, 53)).isSafeInteger());
}

]; // END TEST CASES
Expand Down
5 changes: 5 additions & 0 deletions types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,11 @@ export declare class Long {
*/
isPositive(): boolean;

/**
* Tests if this Long can be safely represented as a JavaScript number.
*/
isSafeInteger(): boolean;

/**
* Tests if this Long's value equals zero.
*/
Expand Down

0 comments on commit 2eb79a4

Please sign in to comment.