Skip to content

Commit 2eb79a4

Browse files
committed
Add isSafeInteger to test if a Long can be safely represented as a JS number
1 parent 167d391 commit 2eb79a4

File tree

4 files changed

+37
-0
lines changed

4 files changed

+37
-0
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,9 @@ API
187187
* Long#**isPositive**(): `boolean`<br />
188188
Tests if this Long's value is positive or zero.
189189

190+
* Long#**isSafeInteger**(): `boolean`<br />
191+
Tests if this Long can be safely represented as a JavaScript number.
192+
190193
* Long#**isZero**/**eqz**(): `boolean`<br />
191194
Tests if this Long's value equals zero.
192195

index.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,22 @@ LongPrototype.getNumBitsAbs = function getNumBitsAbs() {
645645
return this.high != 0 ? bit + 33 : bit + 1;
646646
};
647647

648+
/**
649+
* Tests if this Long can be safely represented as a JavaScript number.
650+
* @this {!Long}
651+
* @returns {boolean}
652+
*/
653+
LongPrototype.isSafeInteger = function isSafeInteger() {
654+
// 2^53-1 is the maximum safe value
655+
var top11Bits = this.high >> 21;
656+
// [0, 2^53-1]
657+
if (!top11Bits) return true;
658+
// > 2^53-1
659+
if (this.unsigned) return false;
660+
// [-2^53, -1] except -2^53
661+
return top11Bits === -1 && !(this.low === 0 && this.high === -0x200000);
662+
};
663+
648664
/**
649665
* Tests if this Long's value equals zero.
650666
* @this {!Long}

tests/index.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,19 @@ var tests = [ // BEGIN TEST CASES
232232
var signedFromUnsigned = Long.fromBigInt(values[i].unsigned);
233233
assert.strictEqual(signedFromUnsigned.toBigInt(), values[i].signed);
234234
}
235+
},
236+
237+
function testSafeInteger() {
238+
assert(Long.fromNumber(0).isSafeInteger());
239+
assert(Long.fromNumber(1).isSafeInteger());
240+
assert(Long.fromNumber(-1).isSafeInteger());
241+
assert(!Long.fromNumber(-1).toUnsigned().isSafeInteger());
242+
assert(Long.fromNumber(Math.pow(2, 32)).isSafeInteger());
243+
assert(Long.fromNumber(-Math.pow(2, 32)).isSafeInteger());
244+
assert(Long.fromNumber(Math.pow(2, 53) - 1).isSafeInteger());
245+
assert(Long.fromNumber(-Math.pow(2, 53) + 1).isSafeInteger());
246+
assert(!Long.fromNumber(Math.pow(2, 53)).isSafeInteger());
247+
assert(!Long.fromNumber(-Math.pow(2, 53)).isSafeInteger());
235248
}
236249

237250
]; // END TEST CASES

types.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,11 @@ export declare class Long {
225225
*/
226226
isPositive(): boolean;
227227

228+
/**
229+
* Tests if this Long can be safely represented as a JavaScript number.
230+
*/
231+
isSafeInteger(): boolean;
232+
228233
/**
229234
* Tests if this Long's value equals zero.
230235
*/

0 commit comments

Comments
 (0)