Usage
The code needs a ES2015+ polyfill to work, for example regenerator-runtime/runtime.
require( 'regenerator-runtime/runtime' ) ;
// or
import 'regenerator-runtime/runtime.js' ;
Then
const integer = require( '@aureooms/js-integer' ) ;
// or
import * as integer from '@aureooms/js-integer' ;
Notation
The Notation tries to emulate the notation in bn.js.
Instructions
Prefixes/postfixes are put in parens at the of the line.
Initialization
- [x]
ZZ.from(object, base = undefined, is_negative = 0)
(Base is guessed depending on object type ifundefined
, default is 10.)
Copying
- [x]
a.clone()
- clone number - [x]
a.move(b)
- copya
's' properties tob
Note that we plan to be pure in the future.
Comparison
- [x]
a.cmp(b)
- compare numbers and return-1
(a<
b),0
(a=
b), or1
(a>
b) depending on the comparison result (cmpn
) - [x]
a.lt(b)
-a
less thanb
(n
) - [x]
a.le(b)
-a
less than or equalsb
(n
) - [x]
a.gt(b)
-a
greater thanb
(n
) - [x]
a.ge(b)
-a
greater than or equalsb
(n
) - [x]
a.eq(b)
-a
equalsb
(n
)
Integer Arithmetic
- [x]
a.negate()
- negate sign (ineg
in bn.js) - [x]
a.opposite()
- negate sign (neg
in bn.js) [x]
a.abs()
- absolute value (i
)[x]
a.add(b)
- addition (i
,n
,in
)- [x]
a.sub(b)
- subtraction (i
,n
,in
) - [x]
a.mul(b)
- multiply (i
,n
,in
) - [x]
a.square()
- square (i
,sqr
in bn.js) [x]
a.pow(b)
- raisea
to the power ofb
(i
,n
,in
)[x]
[q,r] = a.divmod(b)
- divide (i
,n
)- [x]
q = a.div(b)
- division quotient (u
,n
) - [x]
r = a.mod(b)
- division remained (u
,n
) (but noumodn
) - [x]
q = a.divround(b)
- rounded division
In the future, remove in-place operations. They make very little sense except in a few exceptional cases like increment/decrement. If the result is too big to fit in the original array we will have to resize it to make it fit anyway. Maybe little endianess would save the day in that case. Who knows... Could use an immutable flag that is set as soon as a shallow copy is made? Then all operations could try to run in-place if no shallow copy exists.
Greatest Common Divisor
- [x]
a.gcd(b)
- GCD - [x]
a.egcd(b)
- Extended GCD results ({ gcd: ..., x: ..., y: ..., u: ..., v: ... }
)
Modular Arithmetic
- [ ]
ZZ(n)
- integers modulon
- [ ]
ZZ(n).get(3)
-returns the equivalence class [3]_n
- [ ]
a.add(b)
- no comment - [ ]
a.sub(b)
- no comment - [ ]
a.mul(b)
- no comment - [ ]
a.inv()
- inversea
modulon
- [ ]
a.square()
- no comment - [ ]
a.pow(b)
- no comment
Bit operations
We should really have two packages:
- One for immutable, keyable, hashable integers.
- One for safe in-place word array manipulation.
There are multiple reasons for this:
- Some bit operations do not really care about endianess
- It only works efficiently with a radix that is a power of 2
Q: Does it make any sense to have those operations defined for unbounded integers?
The following will be implemented in a package to come.
- [ ]
a.or(b)
- or (i
,u
,iu
) - [ ]
a.and(b)
- and (i
,u
,iu
,andln
) (NOTE:andln
is going to be replaced withandn
in future) - [ ]
a.xor(b)
- xor (i
,u
,iu
) - [ ]
a.setn(b)
- set specified bit to1
- [ ]
a.shln(b)
- shift left (i
,u
,iu
) - [ ]
a.shrn(b)
- shift right (i
,u
,iu
) - [ ]
a.testn(b)
- test if specified bit is set - [ ]
a.maskn(b)
- clear bits with indexes higher or equal tob
(i
) - [ ]
a.bincn(b)
- add1 << b
to the number - [ ]
a.notn(w)
- not (for the width specified byw
) (i
)
Test
- [x]
a.sign()
- return -1, 0, 1 - [x]
a.iszero()
- no comments - [x]
a.isone()
- no comments - [x]
a.ispositive()
- no comments - [x]
a.isnegative()
- no comments - [x]
a.isnonnegative()
- no comments - [x]
a.isnonpositive()
- no comments - [x]
a.iseven()
- no comments - [x]
a.isodd()
- no comments - [x]
a.divides(b)
- no comments
Utilities
- [x]
ZZ.has(object)
- returns true if the suppliedobject
is an integer. - [x]
ZZ.max(a, b)
- returna
ifa
larger thanb
. - [x]
ZZ.min(a, b)
- returna
ifa
smaller thanb
. - [ ]
a.bitLength()
- get number of bits occupied - [ ]
a.zeroBits()
- return number of less-significant consequent zero bits (example:1010000
has 4 zero bits) - [ ]
a.byteLength()
- return number of bytes occupied - [ ]
a.toTwos(width)
- convert to two's complement representation, wherewidth
is bit width - [ ]
a.fromTwos(width)
- convert from two's complement representation, wherewidth
is the bit width
Conversion
- [x]
a.toString(base=10)
- convert to base-string (No zero padding, this is up to you) - [x]
a.bin()
- alias fora.toString(2)
- [x]
a.oct()
- alias fora.toString(8)
- [x]
a.hex()
- alias fora.toString(16)
- [x]
d = a.digits(base=10)
- returns little endian array of digits in given base so that d[0] is the first digit, d[1] the second, etc. - [x]
a.bin()
- alias fora.digits(2)
. - [x]
a.valueOf()
- convert to Javascript Number (limited to 53 bitstoNumber
in bn.js) - [x]
a.toJSON()
- convert to JSON compatible hex string (alias oftoString(16)
) - [ ]
a.to(type, endian, length)
- convert to an instance oftype
, which must behave like anArray
(toArrayLike
in bn.js) - [ ]
a.toArray(endian, length)
- convert to byteArray
, and optionally zero pad to length, throwing if already exceeding - [ ]
a.toBuffer(endian, length)
- convert to Node.js Buffer (if available). For compatibility with browserify and similar tools, use this instead:a.toArrayLike(Buffer, endian, length)
Examples
More examples in the test files.
import { ZZ } from '@aureooms/js-integer' ;
const a = ZZ.from( 'dead' , 16 ) ;
const b = ZZ.from( '101010' , 2 ) ;
const c = a.add(b);
console.log(c.toString()); // 57047
Note: decimals are not supported in this library.