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)-aless thanb(n) - [x]
a.le(b)-aless than or equalsb(n) - [x]
a.gt(b)-agreater thanb(n) - [x]
a.ge(b)-agreater than or equalsb(n) - [x]
a.eq(b)-aequalsb(n)
Integer Arithmetic
- [x]
a.negate()- negate sign (inegin bn.js) - [x]
a.opposite()- negate sign (negin 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,sqrin bn.js) [x]
a.pow(b)- raiseato 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()- inverseamodulon - [ ]
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:andlnis going to be replaced withandnin 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 << bto 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 suppliedobjectis an integer. - [x]
ZZ.max(a, b)- returnaifalarger thanb. - [x]
ZZ.min(a, b)- returnaifasmaller thanb. - [ ]
a.bitLength()- get number of bits occupied - [ ]
a.zeroBits()- return number of less-significant consequent zero bits (example:1010000has 4 zero bits) - [ ]
a.byteLength()- return number of bytes occupied - [ ]
a.toTwos(width)- convert to two's complement representation, wherewidthis bit width - [ ]
a.fromTwos(width)- convert from two's complement representation, wherewidthis 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 bitstoNumberin 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(toArrayLikein 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.
