This proposal adds 64-bit integer arithmetic to ECMAScript. The main language features added are:
0L
and 0UL
+
between double
and long
/uint64_t
is to have an output of the type double
. However, ECMAScript makes this more tricky because an innocent-looking snippet like x + 1
would return a Number output under the same rule, even if x
is a Int64
. Therefore, in this proposal, ToNumber throws an exception on 64-bit ints, following SIMD.js, and arithmetic operators hit this case as wellNumber
will often work, but it will sometimes lose precision, leading to difficult bugs. Instead, lo/hi pairs are needed.Math
functions for lo/hi pairs. But if it wouldn't be too hard to get real 64-bit ints, it would be nice to not have to resort to such a stopgap.
Specification-wise, the addition of more numerical types requires pervasive to ECMAScript's representation of numbers. The ES2015 specification identifies ECMAScript Number
s with mathematical numbers. With the addition of integers, and the fact that the set of double-precision floating point values intersects the sets of 64-bit signed and unsigned integers (which intersect each other), numbers in ECMAScript have to be formalized as tagged values. The complete change to the specification text is outside the scope of this strawman, but it will have to be dealt eventually. For the purposes of this strawman, interpret "untagged" numbers as Numbers by default when used as ECMAScript values.
Please file any issues here. The authoritative copy of this document is in the value-spec repo and a rendered, up-to-date copy is hosted here.
Intrinsic name: %Int64%
Global name: Int64
ECMAScript Language Association: The `Int64` object
Intrinsic name: %Int64Prototype%
Global name: Int64.prototype
ECMAScript Language Association: The initial value of the prototype data property of %Int64Constructor%
Intrinsic name: %Uint64%
Global name: Uint64
ECMAScript Language Association: The `Uint64` object
Intrinsic name: %Uint64Prototype%
Global name: Uint64.prototype
ECMAScript Language Association: The initial value of the prototype data property of %Uint64Constructor%
Int64
and Uint64
values be truthy, under the interpretation that it was a mistake to have anything be falsy but things like +
to operate on less precise numbers. Throwing leaves the door open for future operator overloading while maintaining backwards compatibility.
Object
,
Int64
, return argument.Uint64
,
Int64
.Int64
.Number
,
String
, parse the number as a string as described in the section "ToNumber Applied to the String Type"
, throwing a RangeError if the result is not representable exactly in a Int64, including on -0, NaN and Infinity.Object
,
Uint64
, return argument.Int64
,
Uint64
.Uint64
.Number
,
Uint64
.String
, parse the number as a string as described in the section "ToNumber Applied to the String Type"
, throwing a RangeError if the result is not representable exactly in a Uint64, including on -0, NaN and Infinity.No changes needed for Int64 or Uint64; it will throw a TypeError if either operand is a Int64 value because the algorithm will call ToNumber in step 6.a or 6.c, which throws on Int64 values.
It is important for Abstract Relational Comparison to throw on Int64 types because there is no clear scalar boolean interpretation, and allowing it to throw makes it possible overload the operator in the future.
L
is ToInt64(MV of NumericLiteral)UL
is ToUint64(MV of NumericLiteral)No changes needed for Int64 or Uint64. With one Int64 argument and one argument which is a String after ToPrimitive is applied, this will coerce the Int64 value to a string. Otherwise, if either argument is an Int64 value, then ToNumber will be run on step 12. or 14., which would throw a TypeError.
It is important for +
to throw when applied to Int64 types to allow the future definition of operator overloading on +
.
"%NumberPrototype%"
, «[[NumberData]]» ).
The Int64
constructor is the %Int64% intrinsic object and the initial value of the Int64 property of the global object. When called as a constructor, it creates and initializes a new Int64 object. When Int64
is called as a function rather than as a constructor, it performs a type conversion. Int64
has a number of function properties for operating on Int64 values.
Int64
is called with argument value, the following steps are taken:
"%Int64Prototype%"
, «[[Int64Data]]» ).The value of the [[Prototype]] internal slot of the Int64 constructor is the intrinsic object %FunctionPrototype% (19.2.3).
Besides the length
property (whose value is
The value of Int64.MAX_VALUE is the largest positive value of the Int64 type, which is 9223372036854775807, tagged as Int64.
This property has the attributes { [[Writable]]:
The value of Int64.MIN_VALUE is the smallest negative value of the Int64 type, which is -9223372036854775808, tagged as Int64.
This property has the attributes { [[Writable]]:
length
of Int64.min
is min
is needed because Math.min
will throw on Int64
values when it tries to convert the to Numbers in the definition of Abstract Relational Comparison.length
of Int64.max
is max
is needed because Math.max
will throw on Int64
values when it tries to convert the to Numbers in the definition of Abstract Relational Comparison.An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement the Int64.prototype.toLocaleString method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of the toLocaleString method is used.
Produces a String value that represents this Int64 value formatted according to the conventions of the host environment’s current locale. This function is implementation-dependent, and it is permissible, but not encouraged, for it to return the same thing as toString.
The meanings of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.
The length property of the toLocaleString method is 0.
The Uint64
constructor is the %Uint64% intrinsic object and the initial value of the Uint64 property of the global object. When called as a constructor, it creates and initializes a new Uint64 object. When Uint64
is called as a function rather than as a constructor, it performs a type conversion. Uint64
has a number of function properties for operating on Uint64 values.
Uint64
is called with argument value, the following steps are taken:
"%Uint64Prototype%"
, «[[Uint64Data]]» ).The value of the [[Prototype]] internal slot of the Uint64 constructor is the intrinsic object %FunctionPrototype% (19.2.3).
Besides the length
property (whose value is
The value of Uint64.MAX_VALUE is the largest positive value of the Uint64 type, which is 18446744073709551615, tagged as Uint64.
This property has the attributes { [[Writable]]:
The value of Int64.MIN_VALUE is the smallest value of the Uint64 type, which is 0, tagged as Int64.
This property has the attributes { [[Writable]]:
compare
.
length
of Uint64.min
is min
is needed because Math.min
will throw on Uint64
values when it tries to convert the to Numbers in the definition of Abstract Relational Comparison.length
of Uint64.max
is max
is needed because Math.max
will throw on Uint64
values when it tries to convert the to Numbers in the definition of Abstract Relational Comparison.An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement the Int64.prototype.toLocaleString method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of the toLocaleString method is used.
Produces a String value that represents this Uint64 value formatted according to the conventions of the host environment’s current locale. This function is implementation-dependent, and it is permissible, but not encouraged, for it to return the same thing as toString.
The meanings of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.
The length property of the toLocaleString method is 0.
getInt64
, setInt64
, getUint64
, and setUint64
are also provided analogously.