1\input texinfo
2
3@iftex
4@afourpaper
5@headings double
6@end iftex
7
8@titlepage
9@afourpaper
10@sp 7
11@center @titlefont{Javascript Bignum Extensions}
12@sp 3
13@center Version 2020-01-11
14@sp 3
15@center Author: Fabrice Bellard
16@end titlepage
17
18@setfilename jsbignum.info
19@settitle Javascript Bignum Extensions
20
21@contents
22
23@chapter Introduction
24
25The Bignum extensions add the following features to the Javascript
26language while being 100% backward compatible:
27
28@itemize
29
30@item Operator overloading with a dispatch logic inspired from the proposal available at @url{https://github.com/tc39/proposal-operator-overloading/}.
31
32@item Arbitrarily large floating point numbers (@code{BigFloat}) in base 2 using the IEEE 754 semantics.
33
34@item Arbitrarily large floating point numbers (@code{BigDecimal}) in base 10 based on the proposal available at
35@url{https://github.com/littledan/proposal-bigdecimal}.
36
37@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
38remainder. @code{^} is an alias to the power operator
39(@code{**}). @code{^^} is used as the exclusive or operator.
40
41@end itemize
42
43The extensions are independent from each other except the @code{math}
44mode which relies on BigFloat and operator overloading.
45
46@chapter Operator overloading
47
48Operator overloading is inspired from the proposal available at
49@url{https://github.com/tc39/proposal-operator-overloading/}. It
50implements the same dispatch logic but finds the operator sets by
51looking at the @code{Symbol.operatorSet} property in the objects. The
52changes were done in order to simplify the implementation.
53
54More precisely, the following modifications were made:
55
56@itemize
57
58@item @code{with operators from} is not supported. Operator overloading is always enabled.
59
60@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.
61
62@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.
63
64@item @code{[]} cannot be overloaded.
65
66@item In math mode, the BigInt division and power operators can be overloaded with @code{Operators.updateBigIntOperators(dictionary)}.
67
68@end itemize
69
70@chapter BigInt extensions
71
72A few properties are added to the BigInt object:
73
74@table @code
75
76@item tdiv(a, b)
77Return @math{trunc(a/b)}. @code{b = 0} raises a RangeError
78exception.
79
80@item fdiv(a, b)
81Return @math{\lfloor a/b \rfloor}. @code{b = 0} raises a RangeError
82exception.
83
84@item cdiv(a, b)
85Return @math{\lceil a/b \rceil}. @code{b = 0} raises a RangeError
86exception.
87
88@item ediv(a, b)
89Return @math{sgn(b) \lfloor a/{|b|} \rfloor} (Euclidian
90division). @code{b = 0} raises a RangeError exception.
91
92@item tdivrem(a, b)
93@item fdivrem(a, b)
94@item cdivrem(a, b)
95@item edivrem(a, b)
96Return an array of two elements. The first element is the quotient,
97the second is the remainder. The same rounding is done as the
98corresponding division operation.
99
100@item sqrt(a)
101Return @math{\lfloor \sqrt(a) \rfloor}. A RangeError exception is
102raised if @math{a < 0}.
103
104@item sqrtrem(a)
105Return an array of two elements. The first element is @math{\lfloor
106\sqrt{a} \rfloor}. The second element is @math{a-\lfloor \sqrt{a}
107\rfloor^2}. A RangeError exception is raised if @math{a < 0}.
108
109@item floorLog2(a)
110Return -1 if @math{a \leq 0} otherwise return @math{\lfloor \log2(a) \rfloor}.
111
112@item ctz(a)
113Return the number of trailing zeros in the two's complement binary representation of a. Return -1 if @math{a=0}.
114
115@end table
116
117@chapter BigFloat
118
119@section Introduction
120
121This extension adds the @code{BigFloat} primitive type. The
122@code{BigFloat} type represents floating point numbers in base 2
123with the IEEE 754 semantics. A floating
124point number is represented as a sign, mantissa and exponent. The
125special values @code{NaN}, @code{+/-Infinity}, @code{+0} and @code{-0}
126are supported. The mantissa and exponent can have any bit length with
127an implementation specific minimum and maximum.
128
129@section Floating point rounding
130
131Each floating point operation operates with infinite precision and
132then rounds the result according to the specified floating point
133environment (@code{BigFloatEnv} object). The status flags of the
134environment are also set according to the result of the operation.
135
136If no floating point environment is provided, the global floating
137point environment is used.
138
139The rounding mode of the global floating point environment is always
140@code{RNDN} (``round to nearest with ties to even'')@footnote{The
141rationale is that the rounding mode changes must always be
142explicit.}. The status flags of the global environment cannot be
143read@footnote{The rationale is to avoid side effects for the built-in
144operators.}. The precision of the global environment is
145@code{BigFloatEnv.prec}. The number of exponent bits of the global
146environment is @code{BigFloatEnv.expBits}. The global environment
147subnormal flag is set to @code{true}.
148
149For example, @code{prec = 53} and @code{ expBits = 11} exactly give
150the same precision as the IEEE 754 64 bit floating point format. The
151default precision is @code{prec = 113} and @code{ expBits = 15} (IEEE
152754 128 bit floating point format).
153
154The global floating point environment can only be modified temporarily
155when calling a function (see @code{BigFloatEnv.setPrec}). Hence a
156function can change the global floating point environment for its
157callees but not for its caller.
158
159@section Operators
160
161The builtin operators are extended so that a BigFloat is returned if
162at least one operand is a BigFloat. The computations are always done
163with infinite precision and rounded according to the global floating
164point environment.
165
166@code{typeof} applied on a @code{BigFloat} returns @code{bigfloat}.
167
168BigFloat can be compared with all the other numeric types and the
169result follows the expected mathematical relations.
170
171However, since BigFloat and Number are different types they are never
172equal when using the strict comparison operators (e.g. @code{0.0 ===
1730.0l} is false).
174
175@section BigFloat literals
176
177BigFloat literals are floating point numbers with a trailing @code{l}
178suffix. BigFloat literals have an infinite precision. They are rounded
179according to the global floating point environment when they are
180evaluated.@footnote{Base 10 floating point literals cannot usually be
181exactly represented as base 2 floating point number. In order to
182ensure that the literal is represented accurately with the current
183precision, it must be evaluated at runtime.}
184
185@section Builtin Object changes
186
187@subsection @code{BigFloat} function
188
189The @code{BigFloat} function cannot be invoked as a constructor. When
190invoked as a function: the parameter is converted to a primitive
191type. If the result is a numeric type, it is converted to BigFloat
192without rounding. If the result is a string, it is converted to
193BigFloat using the precision of the global floating point environment.
194
195@code{BigFloat} properties:
196
197@table @code
198
199@item LN2
200@item PI
201Getter. Return the value of the corresponding mathematical constant
202rounded to nearest, ties to even with the current global
203precision. The constant values are cached for small precisions.
204
205@item MIN_VALUE
206@item MAX_VALUE
207@item EPSILON
208Getter. Return the minimum, maximum and epsilon @code{BigFloat} values
209(same definition as the corresponding @code{Number} constants).
210
211@item fpRound(a[, e])
212Round the floating point number @code{a} according to the floating
213point environment @code{e} or the global environment if @code{e} is
214undefined.
215
216@item parseFloat(a[, radix[, e]])
217Parse the string @code{a} as a floating point number in radix
218@code{radix}. The radix is 0 (default) or from 2 to 36. The radix 0
219means radix 10 unless there is a hexadecimal or binary prefix. The
220result is rounded according to the floating point environment @code{e}
221or the global environment if @code{e} is undefined.
222
223@item isFinite(a)
224Return true if @code{a} is a finite bigfloat.
225
226@item isNaN(a)
227Return true if @code{a} is a NaN bigfloat.
228
229@item add(a, b[, e])
230@item sub(a, b[, e])
231@item mul(a, b[, e])
232@item div(a, b[, e])
233Perform the specified floating point operation and round the floating
234point number @code{a} according to the floating point environment
235@code{e} or the global environment if @code{e} is undefined. If
236@code{e} is specified, the floating point status flags are updated.
237
238@item floor(x)
239@item ceil(x)
240@item round(x)
241@item trunc(x)
242Round to an integer. No additional rounding is performed.
243
244@item abs(x)
245Return the absolute value of x. No additional rounding is performed.
246
247@item fmod(x, y[, e])
248@item remainder(x, y[, e])
249Floating point remainder. The quotient is truncated to zero (fmod) or
250to the nearest integer with ties to even (remainder). @code{e} is an
251optional floating point environment.
252
253@item sqrt(x[, e])
254Square root. Return a rounded floating point number. @code{e} is an
255optional floating point environment.
256
257@item sin(x[, e])
258@item cos(x[, e])
259@item tan(x[, e])
260@item asin(x[, e])
261@item acos(x[, e])
262@item atan(x[, e])
263@item atan2(x, y[, e])
264@item exp(x[, e])
265@item log(x[, e])
266@item pow(x, y[, e])
267Transcendental operations. Return a rounded floating point
268number. @code{e} is an optional floating point environment.
269
270@end table
271
272@subsection @code{BigFloat.prototype}
273
274The following properties are modified:
275
276@table @code
277@item valueOf()
278Return the bigfloat primitive value corresponding to @code{this}.
279
280@item toString(radix)
281
282For floating point numbers:
283
284@itemize
285@item
286If the radix is a power of two, the conversion is done with infinite
287precision.
288@item
289Otherwise, the number is rounded to nearest with ties to even using
290the global precision. It is then converted to string using the minimum
291number of digits so that its conversion back to a floating point using
292the global precision and round to nearest gives the same number.
293
294@end itemize
295
296The exponent letter is @code{e} for base 10, @code{p} for bases 2, 8,
29716 with a binary exponent and @code{@@} for the other bases.
298
299@item toPrecision(p, rnd_mode = BigFloatEnv.RNDNA, radix = 10)
300@item toFixed(p, rnd_mode = BigFloatEnv.RNDNA, radix = 10)
301@item toExponential(p, rnd_mode = BigFloatEnv.RNDNA, radix = 10)
302Same semantics as the corresponding @code{Number} functions with
303BigFloats. There is no limit on the accepted precision @code{p}. The
304rounding mode and radix can be optionally specified. The radix must be
305between 2 and 36.
306
307@end table
308
309@subsection @code{BigFloatEnv} constructor
310
311The @code{BigFloatEnv([p, [,rndMode]]} constructor cannot be invoked as a
312function. The floating point environment contains:
313
314@itemize
315@item the mantissa precision in bits
316
317@item the exponent size in bits assuming an IEEE 754 representation;
318
319@item the subnormal flag (if true, subnormal floating point numbers can
320be generated by the floating point operations).
321
322@item the rounding mode
323
324@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.
325
326@end itemize
327
328@code{new BigFloatEnv([p, [,rndMode]]} creates a new floating point
329environment. The status flags are reset. If no parameter is given the
330precision, exponent bits and subnormal flags are copied from the
331global floating point environment. Otherwise, the precision is set to
332@code{p}, the number of exponent bits is set to @code{expBitsMax} and the
333subnormal flags is set to @code{false}. If @code{rndMode} is
334@code{undefined}, the rounding mode is set to @code{RNDN}.
335
336@code{BigFloatEnv} properties:
337
338@table @code
339
340@item prec
341Getter. Return the precision in bits of the global floating point
342environment. The initial value is @code{113}.
343
344@item expBits
345Getter. Return the exponent size in bits of the global floating point
346environment assuming an IEEE 754 representation. The initial value is
347@code{15}.
348
349@item setPrec(f, p[, e])
350Set the precision of the global floating point environment to @code{p}
351and the exponent size to @code{e} then call the function
352@code{f}. Then the Float precision and exponent size are reset to
353their precious value and the return value of @code{f} is returned (or
354an exception is raised if @code{f} raised an exception). If @code{e}
355is @code{undefined} it is set to @code{BigFloatEnv.expBitsMax}.
356
357@item precMin
358Read-only integer. Return the minimum allowed precision. Must be at least 2.
359
360@item precMax
361Read-only integer. Return the maximum allowed precision. Must be at least 113.
362
363@item expBitsMin
364Read-only integer. Return the minimum allowed exponent size in
365bits. Must be at least 3.
366
367@item expBitsMax
368Read-only integer. Return the maximum allowed exponent size in
369bits. Must be at least 15.
370
371@item RNDN
372Read-only integer. Round to nearest, with ties to even rounding mode.
373
374@item RNDZ
375Read-only integer. Round to zero rounding mode.
376
377@item RNDD
378Read-only integer. Round to -Infinity rounding mode.
379
380@item RNDU
381Read-only integer. Round to +Infinity rounding mode.
382
383@item RNDNA
384Read-only integer. Round to nearest, with ties away from zero rounding mode.
385
386@item RNDA
387Read-only integer. Round away from zero rounding mode.
388
389@item RNDF@footnote{Could be removed in case a deterministic behavior for floating point operations is required.}
390Read-only integer. Faithful rounding mode. The result is
391non-deterministically rounded to -Infinity or +Infinity. This rounding
392mode usually gives a faster and deterministic running time for the
393floating point operations.
394
395@end table
396
397@code{BigFloatEnv.prototype} properties:
398
399@table @code
400
401@item prec
402Getter and setter (Integer). Return or set the precision in bits.
403
404@item expBits
405Getter and setter (Integer). Return or set the exponent size in bits
406assuming an IEEE 754 representation.
407
408@item rndMode
409Getter and setter (Integer). Return or set the rounding mode.
410
411@item subnormal
412Getter and setter (Boolean). subnormal flag. It is false when
413@code{expBits = expBitsMax}.
414
415@item clearStatus()
416Clear the status flags.
417
418@item invalidOperation
419@item divideByZero
420@item overflow
421@item underflow
422@item inexact
423Getter and setter (Boolean). Status flags.
424
425@end table
426
427@chapter BigDecimal
428
429This extension adds the @code{BigDecimal} primitive type. The
430@code{BigDecimal} type represents floating point numbers in base
43110. It is inspired from the proposal available at
432@url{https://github.com/littledan/proposal-bigdecimal}.
433
434The @code{BigDecimal} floating point numbers are always normalized and
435finite. There is no concept of @code{-0}, @code{Infinity} or
436@code{NaN}. By default, all the computations are done with infinite
437precision.
438
439@section Operators
440
441The following builtin operators support BigDecimal:
442
443@table @code
444
445@item +
446@item -
447@item *
448Both operands must be BigDecimal. The result is computed with infinite
449precision.
450@item %
451Both operands must be BigDecimal. The result is computed with infinite
452precision. A range error is throws in case of division by zero.
453
454@item /
455Both operands must be BigDecimal. A range error is throws in case of
456division by zero or if the result cannot be represented with infinite
457precision (use @code{BigDecimal.div} to specify the rounding).
458
459@item **
460Both operands must be BigDecimal. The exponent must be a positive
461integer. The result is computed with infinite precision.
462
463@item ===
464When one of the operand is a BigDecimal, return true if both operands
465are a BigDecimal and if they are equal.
466
467@item ==
468@item !=
469@item <=
470@item >=
471@item <
472@item >
473
474Numerical comparison. When one of the operand is not a BigDecimal, it is
475converted to BigDecimal by using ToString(). Hence comparisons between
476Number and BigDecimal do not use the exact mathematical value of the
477Number value.
478
479@end table
480
481@section BigDecimal literals
482
483BigDecimal literals are decimal floating point numbers with a trailing
484@code{m} suffix.
485
486@section Builtin Object changes
487
488@subsection The @code{BigDecimal} function.
489
490It returns @code{0m} if no parameter is provided. Otherwise the first
491parameter is converted to a bigdecimal by using ToString(). Hence
492Number values are not converted to their exact numerical value as
493BigDecimal.
494
495@subsection Properties of the @code{BigDecimal} object
496
497@table @code
498
499@item add(a, b[, e])
500@item sub(a, b[, e])
501@item mul(a, b[, e])
502@item div(a, b[, e])
503@item mod(a, b[, e])
504@item sqrt(a, e)
505@item round(a, e)
506Perform the specified floating point operation and round the floating
507point result according to the rounding object @code{e}. If the
508rounding object is not present, the operation is executed with
509infinite precision.
510
511For @code{div}, a @code{RangeError} exception is thrown in case of
512division by zero or if the result cannot be represented with infinite
513precision if no rounding object is present.
514
515For @code{sqrt}, a range error is thrown if @code{a} is less than
516zero.
517
518The rounding object must contain the following properties:
519@code{roundingMode} is a string specifying the rounding mode
520(@code{"floor"}, @code{"ceiling"}, @code{"down"}, @code{"up"},
521@code{"half-even"}, @code{"half-up"}). Either
522@code{maximumSignificantDigits} or @code{maximumFractionDigits} must
523be present to specify respectively the number of significant digits
524(must be >= 1) or the number of digits after the decimal point (must
525be >= 0).
526
527@end table
528
529@subsection Properties of the @code{BigDecimal.prototype} object
530
531@table @code
532@item valueOf()
533Return the bigdecimal primitive value corresponding to @code{this}.
534
535@item toString()
536Convert @code{this} to a string with infinite precision in base 10.
537
538@item toPrecision(p, rnd_mode = "half-up")
539@item toFixed(p, rnd_mode = "half-up")
540@item toExponential(p, rnd_mode = "half-up")
541Convert the BigDecimal @code{this} to string with the specified
542precision @code{p}. There is no limit on the accepted precision
543@code{p}. The rounding mode can be optionally
544specified. @code{toPrecision} outputs either in decimal fixed notation
545or in decimal exponential notation with a @code{p} digits of
546precision.  @code{toExponential} outputs in decimal exponential
547notation with @code{p} digits after the decimal point. @code{toFixed}
548outputs in decimal notation with @code{p} digits after the decimal
549point.
550
551@end table
552
553@chapter Math mode
554
555A new @emph{math mode} is enabled with the @code{"use math"}
556directive. It propagates the same way as the @emph{strict mode}. It is
557designed so that arbitrarily large integers and floating point numbers
558are available by default. In order to minimize the number of changes
559in the Javascript semantics, integers are represented either as Number
560or BigInt depending on their magnitude. Floating point numbers are
561always represented as BigFloat.
562
563The following changes are made to the Javascript semantics:
564
565@itemize
566
567@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"}.
568
569@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" }.
570
571@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.
572
573@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.
574
575@item The @code{^} operator is an alias to the power operator (@code{**}).
576
577@item The power operator (both @code{^} and @code{**}) grammar is modified so that @code{-2^2} is allowed and yields @code{-4}.
578
579@item The logical xor operator is still available with the @code{^^} operator.
580
581@item The modulo operator (@code{%}) returns the Euclidian remainder (always positive) instead of the truncated remainder.
582
583@item The integer division operator can be overloaded with @code{Operators.updateBigIntOperators(dictionary)}.
584
585@item The integer power operator with a non zero negative exponent can be overloaded with @code{Operators.updateBigIntOperators(dictionary)}.
586
587@end itemize
588
589@bye
590