Skip to content

Commit 34db729

Browse files
✨ feat(Integer): Implement valueOf.
1 parent d1b6eb4 commit 34db729

File tree

3 files changed

+72
-0
lines changed

3 files changed

+72
-0
lines changed

src/Integer.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import {
88
increment ,
99
} from '@aureooms/js-integer-big-endian' ;
1010

11+
import { MIN_NUMBER , MAX_NUMBER , MAX_BASE } from './_limits' ;
12+
1113
export class Integer {
1214

1315
constructor ( base , is_negative , limbs ) {
@@ -369,4 +371,24 @@ export class Integer {
369371
return this.cmp( other ) !== 0 ;
370372
}
371373

374+
valueOf ( ) {
375+
376+
if (this.gtn(MAX_NUMBER)) throw new ValueError(`Cannot call valueOf on Integer larger than ${MAX_NUMBER}. Got ${this.toString()}`) ;
377+
if (this.ltn(MIN_NUMBER)) throw new ValueError(`Cannot call valueOf on Integer smaller than ${MIN_NUMBER}. Got ${this.toString()}`) ;
378+
379+
const limbs = convert( this.base , MAX_BASE , this.limbs , 0 , this.limbs.length ) ;
380+
381+
const sign = this.is_negative ? -1 : 1 ;
382+
383+
const value = limbs.length === 2 ?
384+
limbs[0] * MAX_BASE + limbs[1] :
385+
limbs[0] ;
386+
387+
return sign * value ;
388+
}
389+
390+
toNumber ( ) {
391+
return this.valueOf( ) ;
392+
}
393+
372394
}

src/_limits.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// The range of valid numbers is -2^53 to 2^53 - 1
2+
export const MAX_NUMBER = Math.pow(2,53) - 1 ;
3+
export const MIN_NUMBER = -Math.pow(2,53) ;
4+
export const MIN_BASE = 2 ;
5+
export const MAX_BASE = Math.ceil(Math.sqrt(Math.pow(2,53))) ;

test/src/Integer/toNumber.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import test from 'ava' ;
2+
3+
import { randint } from '@aureooms/js-random' ;
4+
import { ValueError } from '@aureooms/js-error' ;
5+
6+
import { ZZ , MIN_NUMBER , MAX_NUMBER } from '../../../src' ;
7+
8+
function macro ( t , number ) {
9+
const integer = ZZ.from(number) ;
10+
t.is(number.toString(), integer.toString());
11+
t.is(number, integer.toNumber());
12+
}
13+
14+
macro.title = ( providedTitle , number ) => `toNumber: ${number}` ;
15+
16+
function throws ( t , string ) {
17+
const integer = ZZ.from(string) ;
18+
t.is(string, integer.toString()) ;
19+
t.throws(() => integer.toNumber(), { instanceOf: ValueError }) ;
20+
}
21+
22+
throws.title = ( providedTitle , string ) => `toNumber: ${string} throws` ;
23+
24+
const tested = new Set() ;
25+
const N = 100 ;
26+
27+
const once = x => {
28+
tested.add(x) ;
29+
test( macro , x ) ;
30+
}
31+
32+
once(0);
33+
once(1);
34+
once(-1);
35+
once(MIN_NUMBER);
36+
once(MAX_NUMBER);
37+
38+
while ( tested.size < N ) {
39+
const number = randint(MIN_NUMBER, MAX_NUMBER + 1) ;
40+
if ( tested.has(number) ) continue ;
41+
once(number) ;
42+
}
43+
44+
test( throws , '9007199254740992' ) ;
45+
test( throws , '-9007199254740993' ) ;

0 commit comments

Comments
 (0)