fuchsia / third_party / quickjs / 947002cabd400e196e0865a27ce65951be3b6e86 / . / doc / jsbignum.texi

\input texinfo | |

@iftex | |

@afourpaper | |

@headings double | |

@end iftex | |

@titlepage | |

@afourpaper | |

@sp 7 | |

@center @titlefont{Javascript Bignum Extensions} | |

@sp 3 | |

@center Version 2020-01-11 | |

@sp 3 | |

@center Author: Fabrice Bellard | |

@end titlepage | |

@setfilename jsbignum.info | |

@settitle Javascript Bignum Extensions | |

@contents | |

@chapter Introduction | |

The Bignum extensions add the following features to the Javascript | |

language while being 100% backward compatible: | |

@itemize | |

@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 Arbitrarily large floating point numbers (@code{BigDecimal}) in base 10 based on the proposal available at | |

@url{https://github.com/littledan/proposal-bigdecimal}. | |

@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 BigFloat and operator overloading. | |

@chapter Operator overloading | |

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. | |

More precisely, the following modifications were made: | |

@itemize | |

@item @code{with operators from} is not supported. Operator overloading is always enabled. | |

@item The dispatch is not based on a static @code{[[OperatorSet]]} field in all instances. Instead, a dynamic lookup of the @code{Symbol.operatorSet} property is done. This property is typically added in the prototype of each object. | |

@item @code{Operators.create(...dictionaries)} is used to create a new OperatorSet object. The @code{Operators} function is supported as an helper to be closer to the TC39 proposal. | |

@item @code{[]} cannot be overloaded. | |

@item In math mode, the BigInt division and power operators can be overloaded with @code{Operators.updateBigIntOperators(dictionary)}. | |

@end itemize | |

@chapter BigInt extensions | |

A few properties are added to the BigInt object: | |

@table @code | |

@item tdiv(a, b) | |

Return @math{trunc(a/b)}. @code{b = 0} raises a RangeError | |

exception. | |

@item fdiv(a, b) | |

Return @math{\lfloor a/b \rfloor}. @code{b = 0} raises a RangeError | |

exception. | |

@item cdiv(a, b) | |

Return @math{\lceil a/b \rceil}. @code{b = 0} raises a RangeError | |

exception. | |

@item ediv(a, b) | |

Return @math{sgn(b) \lfloor a/{|b|} \rfloor} (Euclidian | |

division). @code{b = 0} raises a RangeError exception. | |

@item tdivrem(a, b) | |

@item fdivrem(a, b) | |

@item cdivrem(a, b) | |

@item edivrem(a, b) | |

Return an array of two elements. The first element is the quotient, | |

the second is the remainder. The same rounding is done as the | |

corresponding division operation. | |

@item sqrt(a) | |

Return @math{\lfloor \sqrt(a) \rfloor}. A RangeError exception is | |

raised if @math{a < 0}. | |

@item sqrtrem(a) | |

Return an array of two elements. The first element is @math{\lfloor | |

\sqrt{a} \rfloor}. The second element is @math{a-\lfloor \sqrt{a} | |

\rfloor^2}. A RangeError exception is raised if @math{a < 0}. | |

@item floorLog2(a) | |

Return -1 if @math{a \leq 0} otherwise return @math{\lfloor \log2(a) \rfloor}. | |

@item ctz(a) | |

Return the number of trailing zeros in the two's complement binary representation of a. Return -1 if @math{a=0}. | |

@end table | |

@chapter BigFloat | |

@section Introduction | |

This extension adds the @code{BigFloat} primitive type. The | |

@code{BigFloat} type represents floating point numbers in base 2 | |

with the IEEE 754 semantics. A floating | |

point number is represented as a sign, mantissa and exponent. The | |

special values @code{NaN}, @code{+/-Infinity}, @code{+0} and @code{-0} | |

are supported. The mantissa and exponent can have any bit length with | |

an implementation specific minimum and maximum. | |

@section Floating point rounding | |

Each floating point operation operates with infinite precision and | |

then rounds the result according to the specified floating point | |

environment (@code{BigFloatEnv} object). The status flags of the | |

environment are also set according to the result of the operation. | |

If no floating point environment is provided, the global floating | |

point environment is used. | |

The rounding mode of the global floating point environment is always | |

@code{RNDN} (``round to nearest with ties to even'')@footnote{The | |

rationale is that the rounding mode changes must always be | |

explicit.}. The status flags of the global environment cannot be | |

read@footnote{The rationale is to avoid side effects for the built-in | |

operators.}. The precision of the global environment is | |

@code{BigFloatEnv.prec}. The number of exponent bits of the global | |

environment is @code{BigFloatEnv.expBits}. The global environment | |

subnormal flag is set to @code{true}. | |

For example, @code{prec = 53} and @code{ expBits = 11} exactly give | |

the same precision as the IEEE 754 64 bit floating point format. The | |

default precision is @code{prec = 113} and @code{ expBits = 15} (IEEE | |

754 128 bit floating point format). | |

The global floating point environment can only be modified temporarily | |

when calling a function (see @code{BigFloatEnv.setPrec}). Hence a | |

function can change the global floating point environment for its | |

callees but not for its caller. | |

@section Operators | |

The builtin operators are extended so that a BigFloat is returned if | |

at least one operand is a BigFloat. The computations are always done | |

with infinite precision and rounded according to the global floating | |

point environment. | |

@code{typeof} applied on a @code{BigFloat} returns @code{bigfloat}. | |

BigFloat can be compared with all the other numeric types and the | |

result follows the expected mathematical relations. | |

However, since BigFloat and Number are different types they are never | |

equal when using the strict comparison operators (e.g. @code{0.0 === | |

0.0l} is false). | |

@section BigFloat literals | |

BigFloat literals are floating point numbers with a trailing @code{l} | |

suffix. BigFloat literals have an infinite precision. They are rounded | |

according to the global floating point environment when they are | |

evaluated.@footnote{Base 10 floating point literals cannot usually be | |

exactly represented as base 2 floating point number. In order to | |

ensure that the literal is represented accurately with the current | |

precision, it must be evaluated at runtime.} | |

@section Builtin Object changes | |

@subsection @code{BigFloat} function | |

The @code{BigFloat} function cannot be invoked as a constructor. When | |

invoked as a function: the parameter is converted to a primitive | |

type. If the result is a numeric type, it is converted to BigFloat | |

without rounding. If the result is a string, it is converted to | |

BigFloat using the precision of the global floating point environment. | |

@code{BigFloat} properties: | |

@table @code | |

@item LN2 | |

@item PI | |

Getter. Return the value of the corresponding mathematical constant | |

rounded to nearest, ties to even with the current global | |

precision. The constant values are cached for small precisions. | |

@item MIN_VALUE | |

@item MAX_VALUE | |

@item EPSILON | |

Getter. Return the minimum, maximum and epsilon @code{BigFloat} values | |

(same definition as the corresponding @code{Number} constants). | |

@item fpRound(a[, e]) | |

Round the floating point number @code{a} according to the floating | |

point environment @code{e} or the global environment if @code{e} is | |

undefined. | |

@item parseFloat(a[, radix[, e]]) | |

Parse the string @code{a} as a floating point number in radix | |

@code{radix}. The radix is 0 (default) or from 2 to 36. The radix 0 | |

means radix 10 unless there is a hexadecimal or binary prefix. The | |

result is rounded according to the floating point environment @code{e} | |

or the global environment if @code{e} is undefined. | |

@item isFinite(a) | |

Return true if @code{a} is a finite bigfloat. | |

@item isNaN(a) | |

Return true if @code{a} is a NaN bigfloat. | |

@item add(a, b[, e]) | |

@item sub(a, b[, e]) | |

@item mul(a, b[, e]) | |

@item div(a, b[, e]) | |

Perform the specified floating point operation and round the floating | |

point number @code{a} according to the floating point environment | |

@code{e} or the global environment if @code{e} is undefined. If | |

@code{e} is specified, the floating point status flags are updated. | |

@item floor(x) | |

@item ceil(x) | |

@item round(x) | |

@item trunc(x) | |

Round to an integer. No additional rounding is performed. | |

@item abs(x) | |

Return the absolute value of x. No additional rounding is performed. | |

@item fmod(x, y[, e]) | |

@item remainder(x, y[, e]) | |

Floating point remainder. The quotient is truncated to zero (fmod) or | |

to the nearest integer with ties to even (remainder). @code{e} is an | |

optional floating point environment. | |

@item sqrt(x[, e]) | |

Square root. Return a rounded floating point number. @code{e} is an | |

optional floating point environment. | |

@item sin(x[, e]) | |

@item cos(x[, e]) | |

@item tan(x[, e]) | |

@item asin(x[, e]) | |

@item acos(x[, e]) | |

@item atan(x[, e]) | |

@item atan2(x, y[, e]) | |

@item exp(x[, e]) | |

@item log(x[, e]) | |

@item pow(x, y[, e]) | |

Transcendental operations. Return a rounded floating point | |

number. @code{e} is an optional floating point environment. | |

@end table | |

@subsection @code{BigFloat.prototype} | |

The following properties are modified: | |

@table @code | |

@item valueOf() | |

Return the bigfloat primitive value corresponding to @code{this}. | |

@item toString(radix) | |

For floating point numbers: | |

@itemize | |

@item | |

If the radix is a power of two, the conversion is done with infinite | |

precision. | |

@item | |

Otherwise, the number is rounded to nearest with ties to even using | |

the global precision. It is then converted to string using the minimum | |

number of digits so that its conversion back to a floating point using | |

the global precision and round to nearest gives the same number. | |

@end itemize | |

The exponent letter is @code{e} for base 10, @code{p} for bases 2, 8, | |

16 with a binary exponent and @code{@@} for the other bases. | |

@item toPrecision(p, rnd_mode = BigFloatEnv.RNDNA, radix = 10) | |

@item toFixed(p, rnd_mode = BigFloatEnv.RNDNA, radix = 10) | |

@item toExponential(p, rnd_mode = BigFloatEnv.RNDNA, radix = 10) | |

Same semantics as the corresponding @code{Number} functions with | |

BigFloats. There is no limit on the accepted precision @code{p}. The | |

rounding mode and radix can be optionally specified. The radix must be | |

between 2 and 36. | |

@end table | |

@subsection @code{BigFloatEnv} constructor | |

The @code{BigFloatEnv([p, [,rndMode]]} constructor cannot be invoked as a | |

function. The floating point environment contains: | |

@itemize | |

@item the mantissa precision in bits | |

@item the exponent size in bits assuming an IEEE 754 representation; | |

@item the subnormal flag (if true, subnormal floating point numbers can | |

be generated by the floating point operations). | |

@item the rounding mode | |

@item the floating point status. The status flags can only be set by the floating point operations. They can be reset with @code{BigFloatEnv.prototype.clearStatus()} or with the various status flag setters. | |

@end itemize | |

@code{new BigFloatEnv([p, [,rndMode]]} creates a new floating point | |

environment. The status flags are reset. If no parameter is given the | |

precision, exponent bits and subnormal flags are copied from the | |

global floating point environment. Otherwise, the precision is set to | |

@code{p}, the number of exponent bits is set to @code{expBitsMax} and the | |

subnormal flags is set to @code{false}. If @code{rndMode} is | |

@code{undefined}, the rounding mode is set to @code{RNDN}. | |

@code{BigFloatEnv} properties: | |

@table @code | |

@item prec | |

Getter. Return the precision in bits of the global floating point | |

environment. The initial value is @code{113}. | |

@item expBits | |

Getter. Return the exponent size in bits of the global floating point | |

environment assuming an IEEE 754 representation. The initial value is | |

@code{15}. | |

@item setPrec(f, p[, e]) | |

Set the precision of the global floating point environment to @code{p} | |

and the exponent size to @code{e} then call the function | |

@code{f}. Then the Float precision and exponent size are reset to | |

their precious value and the return value of @code{f} is returned (or | |

an exception is raised if @code{f} raised an exception). If @code{e} | |

is @code{undefined} it is set to @code{BigFloatEnv.expBitsMax}. | |

@item precMin | |

Read-only integer. Return the minimum allowed precision. Must be at least 2. | |

@item precMax | |

Read-only integer. Return the maximum allowed precision. Must be at least 113. | |

@item expBitsMin | |

Read-only integer. Return the minimum allowed exponent size in | |

bits. Must be at least 3. | |

@item expBitsMax | |

Read-only integer. Return the maximum allowed exponent size in | |

bits. Must be at least 15. | |

@item RNDN | |

Read-only integer. Round to nearest, with ties to even rounding mode. | |

@item RNDZ | |

Read-only integer. Round to zero rounding mode. | |

@item RNDD | |

Read-only integer. Round to -Infinity rounding mode. | |

@item RNDU | |

Read-only integer. Round to +Infinity rounding mode. | |

@item RNDNA | |

Read-only integer. Round to nearest, with ties away from zero rounding mode. | |

@item RNDA | |

Read-only integer. Round away from zero rounding mode. | |

@item RNDF@footnote{Could be removed in case a deterministic behavior for floating point operations is required.} | |

Read-only integer. Faithful rounding mode. The result is | |

non-deterministically rounded to -Infinity or +Infinity. This rounding | |

mode usually gives a faster and deterministic running time for the | |

floating point operations. | |

@end table | |

@code{BigFloatEnv.prototype} properties: | |

@table @code | |

@item prec | |

Getter and setter (Integer). Return or set the precision in bits. | |

@item expBits | |

Getter and setter (Integer). Return or set the exponent size in bits | |

assuming an IEEE 754 representation. | |

@item rndMode | |

Getter and setter (Integer). Return or set the rounding mode. | |

@item subnormal | |

Getter and setter (Boolean). subnormal flag. It is false when | |

@code{expBits = expBitsMax}. | |

@item clearStatus() | |

Clear the status flags. | |

@item invalidOperation | |

@item divideByZero | |

@item overflow | |

@item underflow | |

@item inexact | |

Getter and setter (Boolean). Status flags. | |

@end table | |

@chapter BigDecimal | |

This extension adds the @code{BigDecimal} primitive type. The | |

@code{BigDecimal} type represents floating point numbers in base | |

10. It is inspired from the proposal available at | |

@url{https://github.com/littledan/proposal-bigdecimal}. | |

The @code{BigDecimal} floating point numbers are always normalized and | |

finite. There is no concept of @code{-0}, @code{Infinity} or | |

@code{NaN}. By default, all the computations are done with infinite | |

precision. | |

@section Operators | |

The following builtin operators support BigDecimal: | |

@table @code | |

@item + | |

@item - | |

@item * | |

Both operands must be BigDecimal. The result is computed with infinite | |

precision. | |

@item % | |

Both operands must be BigDecimal. The result is computed with infinite | |

precision. A range error is throws in case of division by zero. | |

@item / | |

Both operands must be BigDecimal. A range error is throws in case of | |

division by zero or if the result cannot be represented with infinite | |

precision (use @code{BigDecimal.div} to specify the rounding). | |

@item ** | |

Both operands must be BigDecimal. The exponent must be a positive | |

integer. The result is computed with infinite precision. | |

@item === | |

When one of the operand is a BigDecimal, return true if both operands | |

are a BigDecimal and if they are equal. | |

@item == | |

@item != | |

@item <= | |

@item >= | |

@item < | |

@item > | |

Numerical comparison. When one of the operand is not a BigDecimal, it is | |

converted to BigDecimal by using ToString(). Hence comparisons between | |

Number and BigDecimal do not use the exact mathematical value of the | |

Number value. | |

@end table | |

@section BigDecimal literals | |

BigDecimal literals are decimal floating point numbers with a trailing | |

@code{m} suffix. | |

@section Builtin Object changes | |

@subsection The @code{BigDecimal} function. | |

It returns @code{0m} if no parameter is provided. Otherwise the first | |

parameter is converted to a bigdecimal by using ToString(). Hence | |

Number values are not converted to their exact numerical value as | |

BigDecimal. | |

@subsection Properties of the @code{BigDecimal} object | |

@table @code | |

@item add(a, b[, e]) | |

@item sub(a, b[, e]) | |

@item mul(a, b[, e]) | |

@item div(a, b[, e]) | |

@item mod(a, b[, e]) | |

@item sqrt(a, e) | |

@item round(a, e) | |

Perform the specified floating point operation and round the floating | |

point result according to the rounding object @code{e}. If the | |

rounding object is not present, the operation is executed with | |

infinite precision. | |

For @code{div}, a @code{RangeError} exception is thrown in case of | |

division by zero or if the result cannot be represented with infinite | |

precision if no rounding object is present. | |

For @code{sqrt}, a range error is thrown if @code{a} is less than | |

zero. | |

The rounding object must contain the following properties: | |

@code{roundingMode} is a string specifying the rounding mode | |

(@code{"floor"}, @code{"ceiling"}, @code{"down"}, @code{"up"}, | |

@code{"half-even"}, @code{"half-up"}). Either | |

@code{maximumSignificantDigits} or @code{maximumFractionDigits} 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). | |

@end table | |

@subsection Properties of the @code{BigDecimal.prototype} object | |

@table @code | |

@item valueOf() | |

Return the bigdecimal primitive value corresponding to @code{this}. | |

@item toString() | |

Convert @code{this} to a string with infinite precision in base 10. | |

@item toPrecision(p, rnd_mode = "half-up") | |

@item toFixed(p, rnd_mode = "half-up") | |

@item toExponential(p, rnd_mode = "half-up") | |

Convert the BigDecimal @code{this} to string with the specified | |

precision @code{p}. There is no limit on the accepted precision | |

@code{p}. The rounding mode can be optionally | |

specified. @code{toPrecision} outputs either in decimal fixed notation | |

or in decimal exponential notation with a @code{p} digits of | |

precision. @code{toExponential} outputs in decimal exponential | |

notation with @code{p} digits after the decimal point. @code{toFixed} | |

outputs in decimal notation with @code{p} digits after the decimal | |

point. | |

@end table | |

@chapter Math mode | |

A new @emph{math mode} is enabled with the @code{"use math"} | |

directive. It propagates the same way as the @emph{strict mode}. 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. | |

The following changes are made to the Javascript semantics: | |

@itemize | |

@item Floating point literals (i.e. number with a decimal point or an exponent) are @code{BigFloat} by default (i.e. a @code{l} suffix is implied). Hence @code{typeof 1.0 === "bigfloat"}. | |

@item Integer literals (i.e. numbers without a decimal point or an exponent) with or without the @code{n} suffix are @code{BigInt} 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}. Hence @code{typeof 1 === "number "}, @code{typeof 1n === "number"} but @code{typeof 9007199254740992 === "bigint" }. | |

@item 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. | |

@item 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. | |

@item The @code{^} operator is an alias to the power operator (@code{**}). | |

@item The power operator (both @code{^} and @code{**}) grammar is modified so that @code{-2^2} is allowed and yields @code{-4}. | |

@item The logical xor operator is still available with the @code{^^} operator. | |

@item The modulo operator (@code{%}) returns the Euclidian remainder (always positive) instead of the truncated remainder. | |

@item The integer division operator can be overloaded with @code{Operators.updateBigIntOperators(dictionary)}. | |

@item The integer power operator with a non zero negative exponent can be overloaded with @code{Operators.updateBigIntOperators(dictionary)}. | |

@end itemize | |

@bye |