## C-like unsigned integers for Javascript

### Synopsis

Javascript does not natively support handling of unsigned 32 or 64 bits integers. This library provides that functionality, following C behaviour, enabling the writing of algorithms that depend on it. It was designed with performance in mind and tries its best to be as fast as possible. Any improvement is welcome!

### How it works

An unsigned 32 bits integer is represented by an object with its first 16 bits (low bits) and its 16 last ones (high bits). All the supported standard operations on the unsigned integer are then performed transparently.

```
e.g.
10000010000100000100010000100010 (2182104098 or 0x82104422) is represented by:
high=1000001000010000
low= 0100010000100010
```

NB.
In case of overflow, the unsigned integer is *truncated* to its lowest 32 bits (in case of UINT32) or 64 bits (in case of UINT64).

The same applies to 64 bits integers, which are split into 4 16 bits ones.

### Installation

In nodejs:

```
npm install cuint
```

In the browser, include the following (file is located in the *build* directory), and access the constructor with *UINT32*:

`
...

`

### Usage

To instantiate an unsigned 32 bits integer, do any of the following:

```
var UINT32 = require('cuint').UINT32 // NodeJS
UINT32( <low bits>, <high bits> )
UINT32( <number> )
UINT32( '<number>', <radix> ) // radix = 10 by default
```

To instantiate an unsigned 64 bits integer, do any of the following:

```
var UINT64 = require('cuint').UINT64 // NodeJS
UINT64( <low bits>, <high bits> )
UINT64( <first low bits>, <second low bits>, <first high bits>, <second high bits> )
UINT64( <number> )
UINT64( '<number>', <radix> ) // radix = 10 by default
```

### Important

Most methods **do modify** the object they are applied to. For instance, the following is equivalent to `x += y`

```
UINT(x).add( UINT(y) )
```

This allows for chaining and reduces the cost of the emulation.
To have `z = x + y`

, do the following:

```
z = UINT(x).clone().add( UINT(y) )
```

### Examples for UINT32

`UINT32( 2, 1 ) // 65538`

{ remainder: null, _low: 2, _high: 1 }

- Using a number (signed 32 bits integer)

`UINT32( 65538 ) // 65538`

{ remainder: null, _low: 2, _high: 1 }

`UINT32( '65538' ) // 65538`

{ remainder: null, _low: 2, _high: 1 }

`UINT32( '3266489917' )`

{ remainder: null, _low: 44605, _high: 49842 }

- Divide 2 unsigned 32 bits integers - note that the remainder is also provided

`UINT32( '3266489917' ).div( UINT32( '668265263' ) )`

{ remainder:
{ remainder: null
, _low: 385
, _high: 9055
}
, _low: 4
, _high: 0
}

### Examples for UINT64

`UINT64( 2, 1 ) // 4294967298`

{ remainder: null, _a00: 2, _a16: 0, _a32: 1, _a48: 0 }

- Using first/second low and high bits

`UINT64( 2, 1, 0, 0 ) // 65538`

{ remainder: null, _a00: 2, _a16: 1, _a32: 0, _a48: 0 }

- Using a number (signed 32 bits integer)

`UINT64( 65538 ) // 65538`

{ remainder: null, _a00: 2, _a16: 1, _a32: 0, _a48: 0 }

`UINT64( '65538' ) // 65538`

{ remainder: null, _a00: 2, _a16: 1, _a32: 0, _a48: 0 }

`UINT64( '3266489917' )`

{ remainder: null, _a00: 44605, _a16: 49842, _a32: 0, _a48: 0 }

- Divide 2 unsigned 64 bits integers - note that the remainder is also provided

`UINT64( 'F00000000000', 16 ).div( UINT64( '800000000000', 16 ) )`

{ remainder:
{ remainder: null,
_a00: 0,
_a16: 0,
_a32: 28672,
_a48: 0 },
_a00: 1,
_a16: 0,
_a32: 0,
_a48: 0 }

### Methods

Methods specific to *UINT32* and *UINT64*:

`UINT32.fromBits(<low bits>, <high bits>)*`

Set the current *UINT32* object with its low and high bits`UINT64.fromBits(<low bits>, <high bits>)*`

Set the current *UINT64* object with its low and high bits`UINT64.fromBits(<first low bits>, <second low bits>, <first high bits>, <second high bits>)*`

Set the current *UINT64* object with all its low and high bits

Methods common to *UINT32* and *UINT64*:

`UINT.fromNumber(<number>)*`

Set the current *UINT* object from a number (first 32 bits only)`UINT.fromString(<string>, <radix>)`

Set the current *UINT* object from a string`UINT.toNumber()`

Convert this *UINT* to a number`UINT.toString(<radix>)`

Convert this *UINT* to a string`UINT.add(<uint>)*`

Add two *UINT*. The current *UINT* stores the result`UINT.subtract(<uint>)*`

Subtract two *UINT*. The current *UINT* stores the result`UINT.multiply(<uint>)*`

Multiply two *UINT*. The current *UINT* stores the result`UINT.div(<uint>)*`

Divide two *UINT*. The current *UINT* stores the result.
The remainder is made available as the *remainder* property on the *UINT* object.
It can be null, meaning there are no remainder.`UINT.negate()`

Negate the current *UINT*`UINT.equals(<uint>)`

alias `UINT.eq(<uint>)`

Equals`UINT.lessThan(<uint>)`

alias `UINT.lt(<uint>)`

Less than (strict)`UINT.greaterThan(<uint>)`

alias `UINT.gt(<uint>)`

Greater than (strict)`UINT.not()`

Bitwise NOT`UINT.or(<uint>)*`

Bitwise OR`UINT.and(<uint>)*`

Bitwise AND`UINT.xor(<uint>)*`

Bitwise XOR`UINT.shiftRight(<number>)*`

alias `UINT.shiftr(<number>)*`

Bitwise shift right`UINT.shiftLeft(<number>[, <allowOverflow>])*`

alias `UINT.shiftl(<number>[, <allowOverflow>])*`

Bitwise shift left`UINT.rotateLeft(<number>)*`

alias `UINT.rotl(<number>)*`

Bitwise rotate left`UINT.rotateRight(<number>)*`

alias `UINT.rotr(<number>)*`

Bitwise rotate right`UINT.clone()`

Clone the current *UINT*

NB. methods with an * do **modify** the object it is applied to. Input objects are not modified.

### TODO

- more methods:
- signed version

### License

MIT

Written with StackEdit.