1 of 15

Arbitrary precision Integers in JavaScript:

For Stage 2

Daniel Ehrenberg

Igalia

2 of 15

Why do anything?

  • Number can represent integers only up to 253 accurately
  • 64-bit int use cases
    • GUIDs, protobufs with 64-bit ints
    • For Node, fields of stat, other system calls
    • WebAssembly FFI, Uint64Array
    • Accurate timestamps
    • Seek on distributed FS
  • Larger than 64-bit use cases
    • Direct crypto implementation
    • M/L and Scientific workloads with huge domains/ranges that can't lose precision

3 of 15

Why Integer rather than Int64?

  • Infinite precision is most useful/expected by most users
  • Implementer feedback so far: Integer is optimizable
  • Wraparound logic via cast functions: Integer.asUintN/Integer.asIntN
  • Better ergonomics for most users
  • Integer would still be sufficient (even if awkward) to the users preferring Int64

4 of 15

How?

  • New primitive type Integer
  • Literal syntax
  • Operator overloading

1n + 2n

0xffn < 0x100n

let x = 1n; x++;

5 of 15

Code sample

// Takes a Integer as an argument and returns a Integerfunction nthPrime(nth) {� function isPrime(p) {� for (let i = 2n; i < p; i++) {� if (p % i === 0n) return false;� }� return true;� }� for (let i = 2n; ; i++) {� if (isPrime(i)) {� if (--nth === 0n) return i;� }� }�}

6 of 15

Code sample: asm.js (?)

function Add64Module(stdlib, foreign, buffer) {� "use asm";� var cast = stdlib.Integer.asUintN;� var values = new stdlib.Uint64Array(buffer);� function add64(aIndex, bIndex) {� aIndex = aIndex|0;� bIndex = bIndex|0;� var aValue = values[aIndex>>3];� var bValue = values[bIndex>>3];� return cast(64, aValue + bValue);� }� return { add64: add64 };�}

7 of 15

Library features

  • Uint64Array, Int64Array
    • elements are Integers
  • Integer static methods
    • Integer.parseInt
    • Integer.asUintN, Integer.asIntN

8 of 15

No implicit coercion

  • The point of Integers: maintain integer precision
  • No good answer for Integer + Number
  • 0.5 + 2n**53n has an answer outside of the range
  • Solution: Require explicit casts
  • Call Number(), Integer() to convert
    • E.g., Number(1n) + 2.0 => 3.0

9 of 15

No implicit coercion

  • What to do when coercion would happen?
  • Solution: throw a TypeError, on:
    • Integer + Number
    • Integer < Number (?)
    • + Integer
    • Passing an Integer to any Web API expecting a Number
    • Any ToNumber() call in the JS
    • etc
  • Integer === Number ⇒ false

10 of 15

Optimization potential

  • Use fixnum infrastructure to optimize as int64 (sometimes)
  • Could work with asm.js
  • Multiple browsers expressed optimism about implementing with good performance

11 of 15

Specification status

12 of 15

References

13 of 15

Backup slides

14 of 15

Comparison semantics:

current proposal

1 < 1n TypeError

1 == 1n TypeError

1 === 1n false

15 of 15

Comparison semantics:

Allow semantic comparison

1 < 1n false

1 == 1n true

1 === 1n false