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