This proposal is an alternative to “Integer: Arbitrary precision integers in JavaScript” by Daniel Ehrenberg, but it also builds on his work.
Everything mentioned here is work in progress. It is not sure that these ideas will work out:
- They may break the web.
- They may turn out to be too complicated/user-unfriendly.
The current proposal for Integers with arbitrary precisions has pros and cons:
- Pros: It is very clean and paves the way for more operator overloading and user-definable value types in the future.
- Cons: It is only partially backward-compatible. The already existing implicit “small integers” (incl. array indices, Array#entries(), Array#forEach(), etc.) clash with the new “big integers”.
- That is, you can’t tell developers: “Use Integers whenever you can.”
- Instead, best practices are: “Use Numbers for up to 53-bit ints. Use Integers if you need more bits.”
This proposal sketches an alternative approach. It has different pros and cons.
Number is a supertype of Int and Double: Number = Int ∪ Double
- Double:
typeof 123.0 === 'number'
Number.isDouble(123.0) === true
- Converting to Double:
Number.asDouble()
- Int:
typeof 123 === 'number'
Number.isInt(123) === true
Number.isInt(0xFF) === true
- Converting to Int:
Number.asInt()
More tool functions:
Number.parseInt() : Int
(new signature)Number.asUintN(width, theInt)
(works as described in Dan’s proposal)Number.asIntN(width, theInt)
(works as described in Dan’s proposal)
Existing binary operators for numbers are overloaded:
+
,-
*
,/
,%
,**
<<
,>>
,>>>
Signature:
- Signatures where results are Double:
- Int × Double → Double (via coercion)
- Double × Int → Double (via coercion)
- Double × Double → Double
- Signature where the result has arbitrary precision:
- Int × Int → Int (all operators except
/
, see below)
- Int × Int → Int (all operators except
Additionally, new Int-only operators (signature: Int×Int→Int) are introduced:
- Integer division:
div
- Normal division must produce non-integer values, e.g. for
1/2
- Normal division must produce non-integer values, e.g. for
- Bitwise operators:
band
,bor
,bxor
- Shift operators:
shl
,shr
Open question: Will +
and *
having more precision for Ints break code on the web? For example:
- Currently:
9007199254740992 + 1 === 9007199254740992
- With this proposal:
9007199254740992 + 1 === 9007199254740993
- With this proposal,
===
has to coerce if a Double has no decimal fraction:1.0 === 1
The results of bitwise operators stay within 32 bits and are of type Int.
- Unary
+
must coerce to Double, because, among others, asm.js depends on it. - Unary
-
: it is unclear how this operator can be made to work for Ints (which only have a single zero), given that:Object.is(-0, 0) === false
- Int operators: coerce or throw exception if operand types are wrong?
- Naming: Int makes most sense, given
Number.isInteger()
etc.
- Static type checking tools could warn if the operands of a numeric operator mix numbers and integers.
- JSON would automatically get big integer values (more than 53 bits).
- “Integer: Arbitrary precision integers in JavaScript” by Daniel Ehrenberg
- “ES proposal: arbitrary precision integers” by Axel Rauschmayer
Deciding that
1
is now an integer is a backwards-incompatible change.Code could expect two integers being multiplied to end up being a truncated float.