<li><aname="toc-Changes-that-introduce-incompatibilities-with-Javascript"href="#Changes-that-introduce-incompatibilities-with-Javascript">3.2 Changes that introduce incompatibilities with Javascript</a>
<ulclass="no-bullet">
<li><aname="toc-Standard-mode"href="#Standard-mode">3.2.1 Standard mode</a></li>
<li><aname="toc-Arbitrarily-large-floating-point-numbers"href="#Arbitrarily-large-floating-point-numbers">4 Arbitrarily large floating point numbers</a>
<li><aname="toc-The-BigDecimal-function_002e"href="#The-BigDecimal-function_002e">5.3.1 The <code>BigDecimal</code> function.</a></li>
<li><aname="toc-Properties-of-the-BigDecimal-object"href="#Properties-of-the-BigDecimal-object">5.3.2 Properties of the <code>BigDecimal</code> object</a></li>
<li><aname="toc-Properties-of-the-BigDecimal_002eprototype-object"href="#Properties-of-the-BigDecimal_002eprototype-object">5.3.3 Properties of the <code>BigDecimal.prototype</code> object</a></li>
to support new types such as complex numbers, fractions or matrices.
</li><li> Bigint mode where arbitrarily large integers are available by default (no <code>n</code> suffix is necessary as in the TC39 BigInt proposal<aname="DOCF1"href="#FOOT1"><sup>1</sup></a>).
<li> Operator overloading with a dispatch logic inspired from the proposal available at <ahref="https://github.com/tc39/proposal-operator-overloading/">https://github.com/tc39/proposal-operator-overloading/</a>.
</li><li> Arbitrarily large floating point numbers (<code>BigFloat</code>) in base 2 using the IEEE 754 semantics.
</li><li> Optional <code>math</code> mode which modifies the semantics of the division, modulo and power operator. The division and power operator return a fraction with integer operands and the modulo operator is defined as the Euclidian remainder.
</li><li> Arbitrarily large floating point numbers (<code>BigDecimal</code>) in base 10 based on the proposal available at
</li><li><code>math</code> mode: arbitrarily large integers and floating point numbers are available by default. The integer division and power can be overloaded for example to return a fraction. The modulo operator (<code>%</code>) is defined as the Euclidian
remainder. <code>^</code> is an alias to the power operator
(<code>**</code>). <code>^^</code> is used as the exclusive or operator.
</li></ul>
<p>The extensions are independent from each other except the <code>math</code>
mode which relies on the bigint mode and the operator overloading.
mode which relies on BigFloat and operator overloading.
</p>
<aname="Operator-overloading"></a>
<h2class="chapter">2 Operator overloading</h2>
<aname="Introduction-1"></a>
<h3class="section">2.1 Introduction</h3>
<p>If the operands of an operator have at least one object type, a custom
operator method is searched before doing the legacy Javascript
<code>ToNumber</code> conversion.
</p>
<p>For unary operators, the custom function is looked up in the object
and has the following name:
</p>
<dlcompact="compact">
<dt><code>unary +</code></dt>
<dd><p><code>Symbol.operatorPlus</code>
</p>
</dd>
<dt><code>unary -</code></dt>
<dd><p><code>Symbol.operatorNeg</code>
</p>
</dd>
<dt><code>++</code></dt>
<dd><p><code>Symbol.operatorInc</code>
</p>
</dd>
<dt><code>--</code></dt>
<dd><p><code>Symbol.operatorDec</code>
</p>
</dd>
<dt><code>~</code></dt>
<dd><p><code>Symbol.operatorNot</code>
</p>
</dd>
</dl>
<p>For binary operators:
</p>
<ul>
<li> If both operands have the same constructor function, then the operator
is looked up in the constructor.
</li><li> Otherwise, the property <code>Symbol.operatorOrder</code> is looked up in both
constructors and converted to <code>Int32</code>. The operator is then
looked in the constructor with the larger <code>Symbol.operatorOrder</code>
value. A <code>TypeError</code> is raised if both constructors have the same
<code>Symbol.operatorOrder</code> value.
</li></ul>
<p>The operator is looked up with the following name:
instead of <code>number</code> (floating point number). In order to be able
to exchange data between standard and bigint modes, numbers are
internally represented as 3 different types:
<p>More precisely, the following modifications were made:
</p>
<ul>
<li>Small integer (SmallInt): 32 bit integer<aname="DOCF3"href="#FOOT3"><sup>3</sup></a>.
<li><code>with operators from</code> is not supported. Operator overloading is always enabled.
</li><li>Big integer (BigInt): arbitrarily large integer.
</li><li> The dispatch is not based on a static <code>[[OperatorSet]]</code> field in all instances. Instead, a dynamic lookup the of the <code>Symbol.operatorSet</code> property is done. This property is typically added in the prototype of each object.
</li><li>Floating point number (Float).
</li><li><code>Operators.create(...dictionaries)</code> is used to create a new OperatorSet object. The <code>Operators</code> function is supported as an helper to be closer to the TC39 proposal.
</li></ul>
<p>In standard mode, the semantics of each operation is modified so that
when it returns a <code>number</code>, it is either of SmallInt or
Float. But the difference between SmallInt and Float is not observable
in standard mode.
</p>
<p>In bigint mode, each operation behaves differently whether its
operands are integer or float. The difference between SmallInt and
BigInt is not observable (i.e. they are both integers).
</p>
<p>The following table summarizes the observable types:
<h3class="section">3.2 Changes that introduce incompatibilities with Javascript</h3>
</li><li><code>[]</code> cannot be overloaded.
<aname="Standard-mode"></a>
<h4class="subsection">3.2.1 Standard mode</h4>
<p>There is no incompatibility with Javascript.
</p>
<aname="Bigint-mode"></a>
<h4class="subsection">3.2.2 Bigint mode</h4>
<p>The following changes are visible:
</p>
<ul>
<li> Integer and Float are different types. Constants are typed. For example: <code>typeof 1.0 === "number"</code> and <code>typeof 1 === "bigint"</code>. Another consequence is that <code>1.0 === 1</code> is false.
</li><li> The range of integers is unlimited. In standard mode: <code>2**53 + 1 === 2**53</code>. This is no longer true with the bignum extensions.
</li><li> Binary bitwise operators do not truncate to 32 bits i.e. <code>0x800000000 | 1 === 0x800000001</code> while it gives <code>1</code> in standard mode.
</li><li> Bitwise shift operators do not truncate to 32 bits and do not mask the shift count with <code>0x1f</code> i.e. <code>1 << 32 === 4294967296</code> while it gives <code>1</code> in standard mode. However, the <code>>>></code> operator (unsigned right shift) which is useless with bignums keeps its standard mode behavior<aname="DOCF4"href="#FOOT4"><sup>4</sup></a>.
</li><li> Operators with integer operands never return the minus zero floating point value as result. Hence <code>Object.is(0, -0) === true</code>. Use <code>-0.0</code> to create a minus zero floating point value.
</li><li> The <code>ToPrimitive</code> abstract operation is called with the <code>"integer"</code> preferred type when an integer is required (e.g. for bitwise binary or shift operations).
</li><li> The prototype of integers is no longer <code>Number.prototype</code>. Instead<br><code>Object.getPrototypeOf(1) === BigInt.prototype</code>. The prototype of floats remains Number.prototype.
</li><li> If the TC39 BigInt proposal is supported, there is no observable difference between integers and <code>bigint</code>s.
</li><li> In math mode, the BigInt division and power operators can be overloaded with <code>Operators.updateBigIntOperators(dictionary)</code>.
<h2class="chapter">4 Arbitrarily large floating point numbers</h2>
<aname="Introduction-3"></a>
<aname="Introduction-1"></a>
<h3class="section">4.1 Introduction</h3>
<p>This extension adds the <code>BigFloat</code> primitive type. The
@ -628,8 +213,8 @@ environment are also set according to the result of the operation.
point environment is used.
</p>
<p>The rounding mode of the global floating point environment is always
<code>RNDN</code> (“round to nearest with ties to even”)<aname="DOCF5" href="#FOOT5"><sup>5</sup></a>. The status flags of the global environment cannot be
read<aname="DOCF6" href="#FOOT6"><sup>6</sup></a>. The precision of the global environment is
<code>RNDN</code> (“round to nearest with ties to even”)<aname="DOCF1" href="#FOOT1"><sup>1</sup></a>. The status flags of the global environment cannot be
read<aname="DOCF2" href="#FOOT2"><sup>2</sup></a>. The precision of the global environment is
<code>BigFloatEnv.prec</code>. The number of exponent bits of the global
environment is <code>BigFloatEnv.expBits</code>. If <code>BigFloatEnv.expBits</code> is
strictly smaller than the maximum allowed number of exponent bits
@ -646,7 +231,7 @@ when calling a function (see <code>BigFloatEnv.setPrec</code>). Hence a
function can change the global floating point environment for its
callees but not for its caller.
</p>
<aname="Operators-1"></a>
<aname="Operators"></a>
<h3class="section">4.3 Operators</h3>
<p>The builtin operators are extended so that a BigFloat is returned if
@ -669,9 +254,9 @@ equal when using the strict comparison operators (e.g. <code>0.0 ===
<p>BigFloat literals are floating point numbers with a trailing <code>l</code>
suffix. BigFloat literals have an infinite precision. They are rounded
according to the global floating point environment when they are
<code>"half-even"</code>, <code>"half-up"</code>). Either
<code>maximumSignificantDigits</code> or <code>maximumFractionDigits</code> must
be present to specify respectively the number of significant digits
(must be >= 1) or the number of digits after the decimal point (must
be >= 0).
</p>
</dd>
</dl>
</li><li> The power operator (both <code>^</code> and <code>**</code>) grammar is modified so that <code>-2^2</code> is allowed and yields <code>-4</code>.
<dd><p>Convert the BigDecimal <code>this</code> to string with the specified
precision <code>p</code>. There is no limit on the accepted precision
<code>p</code>. The rounding mode can be optionally
specified. <code>toPrecision</code> outputs either in decimal fixed notation
or in decimal exponential notation with a <code>p</code> digits of
precision. <code>toExponential</code> outputs in decimal exponential
notation with <code>p</code> digits after the decimal point. <code>toFixed</code>
outputs in decimal notation with <code>p</code> digits after the decimal
point.
</p>
</dd>
</dl>
</li><li> The division operator invokes <code>BigInt[Symbol.operatorDiv]</code> in case both operands are integers.
<aname="Math-mode"></a>
<h2class="chapter">6 Math mode</h2>
</li><li> The power operator invokes <code>BigInt[Symbol.operatorPow]</code> in case both operands are integers and the exponent is strictly negative.
<p>A new <em>math mode</em> is enabled with the <code>"use math"</code>
directive. It propagates the same way as the <em>strict mode</em>. It is
designed so that arbitrarily large integers and floating point numbers
are available by default. In order to minimize the number of changes
in the Javascript semantics, integers are represented either as Number
or BigInt depending on their magnitude. Floating point numbers are
always represented as BigFloat.
</p>
<p>The following changes are made to the Javascript semantics:
</p>
<ul>
<li> Floating point literals (i.e. number with a decimal point or an exponent) are <code>BigFloat</code> by default (i.e. a <code>l</code> suffix is implied). Hence <code>typeof 1.0 === "bigfloat"</code>.
</li><li> The modulo operator returns the Euclidian remainder (always positive) instead of the truncated remainder.
</li><li>Integer literals (i.e. numbers without a decimal point or an exponent) with or without the <code>n</code> suffix are <code>BigInt</code> if their value cannot be represented as a safe integer. A safe integer is defined as a integer whose absolute value is smaller or equal to <code>2**53-1</code>. Hence <code>typeof 1 === "number "</code>, <code>typeof 1n === "number"</code> but <code>typeof 9007199254740992 === "bigint"</code>.
</li><li> Floating point literals are <code>BigFloat</code> by default (i.e. a <code>l</code> suffix is implied).
</li><li>All the bigint builtin operators and functions are modified so that their result is returned as a Number if it is a safe integer. Otherwise the result stays a BigInt.
</li></ul>
</li><li> The builtin operators are modified so that they return an exact result (which can be a BigInt) if their operands are safe integers. Operands between Number and BigInt are accepted provided the Number operand is a safe integer. The integer power with a negative exponent returns a BigFloat as result. The integer division returns a BigFloat as result.
</li><li> The power operator (both <code>^</code> and <code>**</code>) grammar is modified so that <code>-2^2</code> is allowed and yields <code>-4</code>.
<p>The following global symbol is added for the operator overloading:
</p><dlcompact="compact">
<dt><code>operatorMathMod</code></dt>
</dl>
</li><li> The logical xor operator is still available with the <code>^^</code> operator.
<aname="Remaining-issues"></a>
<h3class="section">5.3 Remaining issues</h3>
</li><li> The integer division operator can be overloaded by modifying the corresponding operator in <code>BigInt.prototype.[[OperatorSet]]</code>.
<ol>
<li> A new floating point literal suffix could be added for <code>Number</code> literals.
</li><li> The integer power operator with a non zero negative exponent can be overloaded by modifying the corresponding operator in <code>BigInt.prototype.[[OperatorSet]]</code>.
</li></ol>
</li><li> The modulo operator (<code>%</code>) returns the Euclidian remainder (always positive) instead of the truncated remainder.
@ -27,348 +27,52 @@ language while being 100% backward compatible:
@itemize
@item Overloading of the standard operators
to support new types such as complex numbers, fractions or matrices.
@item Bigint mode where arbitrarily large integers are available by default (no @code{n} suffix is necessary as in the TC39 BigInt proposal@footnote{@url{https://tc39.github.io/proposal-bigint/}}).
@item Operator overloading with a dispatch logic inspired from the proposal available at @url{https://github.com/tc39/proposal-operator-overloading/}.
@item Arbitrarily large floating point numbers (@code{BigFloat}) in base 2 using the IEEE 754 semantics.
@item Optional @code{math} mode which modifies the semantics of the division, modulo and power operator. The division and power operator return a fraction with integer operands and the modulo operator is defined as the Euclidian remainder.
@item Arbitrarily large floating point numbers (@code{BigDecimal}) in base 10 based on the proposal available at
@item @code{math} mode: arbitrarily large integers and floating point numbers are available by default. The integer division and power can be overloaded for example to return a fraction. The modulo operator (@code{%}) is defined as the Euclidian
remainder. @code{^} is an alias to the power operator
(@code{**}). @code{^^} is used as the exclusive or operator.
@end itemize
The extensions are independent from each other except the @code{math}
mode which relies on the bigint mode and the operator overloading.
mode which relies on BigFloat and operator overloading.
@chapter Operator overloading
@section Introduction
If the operands of an operator have at least one object type, a custom
operator method is searched before doing the legacy Javascript
@code{ToNumber} conversion.
For unary operators, the custom function is looked up in the object
and has the following name:
@table @code
@item unary +
@code{Symbol.operatorPlus}
@item unary -
@code{Symbol.operatorNeg}
@item ++
@code{Symbol.operatorInc}
@item --
@code{Symbol.operatorDec}
@item ~
@code{Symbol.operatorNot}
@end table
For binary operators:
@itemize
@item
If both operands have the same constructor function, then the operator
is looked up in the constructor.
@item
Otherwise, the property @code{Symbol.operatorOrder} is looked up in both
constructors and converted to @code{Int32}. The operator is then
looked in the constructor with the larger @code{Symbol.operatorOrder}
value. A @code{TypeError} is raised if both constructors have the same
@code{Symbol.operatorOrder} value.
@end itemize
The operator is looked up with the following name:
@table @code
@item +
@code{Symbol.operatorAdd}
@item -
@code{Symbol.operatorSub}
@item *
@code{Symbol.operatorMul}
@item /
@code{Symbol.operatorDiv}
@item %
@code{Symbol.operatorMod}
@item % (math mode)
@code{Symbol.operatorMathMod}
@item **
@code{Symbol.operatorPow}
@item |
@code{Symbol.operatorOr}
@item ^
@code{Symbol.operatorXor}
@item &
@code{Symbol.operatorAnd}
@item <<
@code{Symbol.operatorShl}
@item >>
@code{Symbol.operatorShr}
@item <
@code{Symbol.operatorCmpLT}
@item >
@code{Symbol.operatorCmpLT}, operands swapped
@item <=
@code{Symbol.operatorCmpLE}
@item >=
@code{Symbol.operatorCmpLE}, operands swapped
@item ==, !=
@code{Symbol.operatorCmpEQ}
@end table
The return value of @code{Symbol.operatorCmpLT}, @code{Symbol.operatorCmpLE} and
@code{Symbol.operatorCmpEQ} is converted to @code{Boolean}.
@section Builtin Object changes
@subsection @code{Symbol} constructor
The following global symbols are added for the operator overloading:
@table @code
@item operatorOrder
@item operatorAdd
@item operatorSub
@item operatorMul
@item operatorDiv
@item operatorMod
@item operatorPow
@item operatorShl
@item operatorShr
@item operatorAnd
@item operatorOr
@item operatorXor
@item operatorCmpLT
@item operatorCmpLE
@item operatorCmpEQ
@item operatorPlus
@item operatorNeg
@item operatorNot
@item operatorInc
@item operatorDec
@end table
@chapter The BigInt Mode
Operator overloading is inspired from the proposal available at
@url{https://github.com/tc39/proposal-operator-overloading/}. It
implements the same dispatch logic but finds the operator sets by
looking at the @code{Symbol.operatorSet} property in the objects. The
changes were done in order to simplify the implementation.
@section Introduction
The bigint mode is enabled with the @code{"use bigint"} directive. It
propagates the same way as the strict mode. In bigint mode, all
integers are considered as @code{bigint} (arbitrarily large integer,