jsbignum.texi (20718B)
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 25 The Bignum extensions add the following features to the Javascript 26 language 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 38 remainder. @code{^} is an alias to the power operator 39 (@code{**}). @code{^^} is used as the exclusive or operator. 40 41 @end itemize 42 43 The extensions are independent from each other except the @code{math} 44 mode which relies on BigFloat and operator overloading. 45 46 @chapter Operator overloading 47 48 Operator overloading is inspired from the proposal available at 49 @url{https://github.com/tc39/proposal-operator-overloading/}. It 50 implements the same dispatch logic but finds the operator sets by 51 looking at the @code{Symbol.operatorSet} property in the objects. The 52 changes were done in order to simplify the implementation. 53 54 More 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 72 A few properties are added to the BigInt object: 73 74 @table @code 75 76 @item tdiv(a, b) 77 Return @math{trunc(a/b)}. @code{b = 0} raises a RangeError 78 exception. 79 80 @item fdiv(a, b) 81 Return @math{\lfloor a/b \rfloor}. @code{b = 0} raises a RangeError 82 exception. 83 84 @item cdiv(a, b) 85 Return @math{\lceil a/b \rceil}. @code{b = 0} raises a RangeError 86 exception. 87 88 @item ediv(a, b) 89 Return @math{sgn(b) \lfloor a/{|b|} \rfloor} (Euclidian 90 division). @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) 96 Return an array of two elements. The first element is the quotient, 97 the second is the remainder. The same rounding is done as the 98 corresponding division operation. 99 100 @item sqrt(a) 101 Return @math{\lfloor \sqrt(a) \rfloor}. A RangeError exception is 102 raised if @math{a < 0}. 103 104 @item sqrtrem(a) 105 Return 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) 110 Return -1 if @math{a \leq 0} otherwise return @math{\lfloor \log2(a) \rfloor}. 111 112 @item ctz(a) 113 Return 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 121 This extension adds the @code{BigFloat} primitive type. The 122 @code{BigFloat} type represents floating point numbers in base 2 123 with the IEEE 754 semantics. A floating 124 point number is represented as a sign, mantissa and exponent. The 125 special values @code{NaN}, @code{+/-Infinity}, @code{+0} and @code{-0} 126 are supported. The mantissa and exponent can have any bit length with 127 an implementation specific minimum and maximum. 128 129 @section Floating point rounding 130 131 Each floating point operation operates with infinite precision and 132 then rounds the result according to the specified floating point 133 environment (@code{BigFloatEnv} object). The status flags of the 134 environment are also set according to the result of the operation. 135 136 If no floating point environment is provided, the global floating 137 point environment is used. 138 139 The rounding mode of the global floating point environment is always 140 @code{RNDN} (``round to nearest with ties to even'')@footnote{The 141 rationale is that the rounding mode changes must always be 142 explicit.}. The status flags of the global environment cannot be 143 read@footnote{The rationale is to avoid side effects for the built-in 144 operators.}. The precision of the global environment is 145 @code{BigFloatEnv.prec}. The number of exponent bits of the global 146 environment is @code{BigFloatEnv.expBits}. The global environment 147 subnormal flag is set to @code{true}. 148 149 For example, @code{prec = 53} and @code{ expBits = 11} exactly give 150 the same precision as the IEEE 754 64 bit floating point format. The 151 default precision is @code{prec = 113} and @code{ expBits = 15} (IEEE 152 754 128 bit floating point format). 153 154 The global floating point environment can only be modified temporarily 155 when calling a function (see @code{BigFloatEnv.setPrec}). Hence a 156 function can change the global floating point environment for its 157 callees but not for its caller. 158 159 @section Operators 160 161 The builtin operators are extended so that a BigFloat is returned if 162 at least one operand is a BigFloat. The computations are always done 163 with infinite precision and rounded according to the global floating 164 point environment. 165 166 @code{typeof} applied on a @code{BigFloat} returns @code{bigfloat}. 167 168 BigFloat can be compared with all the other numeric types and the 169 result follows the expected mathematical relations. 170 171 However, since BigFloat and Number are different types they are never 172 equal when using the strict comparison operators (e.g. @code{0.0 === 173 0.0l} is false). 174 175 @section BigFloat literals 176 177 BigFloat literals are floating point numbers with a trailing @code{l} 178 suffix. BigFloat literals have an infinite precision. They are rounded 179 according to the global floating point environment when they are 180 evaluated.@footnote{Base 10 floating point literals cannot usually be 181 exactly represented as base 2 floating point number. In order to 182 ensure that the literal is represented accurately with the current 183 precision, it must be evaluated at runtime.} 184 185 @section Builtin Object changes 186 187 @subsection @code{BigFloat} function 188 189 The @code{BigFloat} function cannot be invoked as a constructor. When 190 invoked as a function: the parameter is converted to a primitive 191 type. If the result is a numeric type, it is converted to BigFloat 192 without rounding. If the result is a string, it is converted to 193 BigFloat 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 201 Getter. Return the value of the corresponding mathematical constant 202 rounded to nearest, ties to even with the current global 203 precision. The constant values are cached for small precisions. 204 205 @item MIN_VALUE 206 @item MAX_VALUE 207 @item EPSILON 208 Getter. Return the minimum, maximum and epsilon @code{BigFloat} values 209 (same definition as the corresponding @code{Number} constants). 210 211 @item fpRound(a[, e]) 212 Round the floating point number @code{a} according to the floating 213 point environment @code{e} or the global environment if @code{e} is 214 undefined. 215 216 @item parseFloat(a[, radix[, e]]) 217 Parse 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 219 means radix 10 unless there is a hexadecimal or binary prefix. The 220 result is rounded according to the floating point environment @code{e} 221 or the global environment if @code{e} is undefined. 222 223 @item isFinite(a) 224 Return true if @code{a} is a finite bigfloat. 225 226 @item isNaN(a) 227 Return 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]) 233 Perform the specified floating point operation and round the floating 234 point 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) 242 Round to an integer. No additional rounding is performed. 243 244 @item abs(x) 245 Return the absolute value of x. No additional rounding is performed. 246 247 @item fmod(x, y[, e]) 248 @item remainder(x, y[, e]) 249 Floating point remainder. The quotient is truncated to zero (fmod) or 250 to the nearest integer with ties to even (remainder). @code{e} is an 251 optional floating point environment. 252 253 @item sqrt(x[, e]) 254 Square root. Return a rounded floating point number. @code{e} is an 255 optional 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]) 267 Transcendental operations. Return a rounded floating point 268 number. @code{e} is an optional floating point environment. 269 270 @end table 271 272 @subsection @code{BigFloat.prototype} 273 274 The following properties are modified: 275 276 @table @code 277 @item valueOf() 278 Return the bigfloat primitive value corresponding to @code{this}. 279 280 @item toString(radix) 281 282 For floating point numbers: 283 284 @itemize 285 @item 286 If the radix is a power of two, the conversion is done with infinite 287 precision. 288 @item 289 Otherwise, the number is rounded to nearest with ties to even using 290 the global precision. It is then converted to string using the minimum 291 number of digits so that its conversion back to a floating point using 292 the global precision and round to nearest gives the same number. 293 294 @end itemize 295 296 The exponent letter is @code{e} for base 10, @code{p} for bases 2, 8, 297 16 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) 302 Same semantics as the corresponding @code{Number} functions with 303 BigFloats. There is no limit on the accepted precision @code{p}. The 304 rounding mode and radix can be optionally specified. The radix must be 305 between 2 and 36. 306 307 @end table 308 309 @subsection @code{BigFloatEnv} constructor 310 311 The @code{BigFloatEnv([p, [,rndMode]]} constructor cannot be invoked as a 312 function. 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 320 be 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 329 environment. The status flags are reset. If no parameter is given the 330 precision, exponent bits and subnormal flags are copied from the 331 global floating point environment. Otherwise, the precision is set to 332 @code{p}, the number of exponent bits is set to @code{expBitsMax} and the 333 subnormal 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 341 Getter. Return the precision in bits of the global floating point 342 environment. The initial value is @code{113}. 343 344 @item expBits 345 Getter. Return the exponent size in bits of the global floating point 346 environment assuming an IEEE 754 representation. The initial value is 347 @code{15}. 348 349 @item setPrec(f, p[, e]) 350 Set the precision of the global floating point environment to @code{p} 351 and the exponent size to @code{e} then call the function 352 @code{f}. Then the Float precision and exponent size are reset to 353 their precious value and the return value of @code{f} is returned (or 354 an exception is raised if @code{f} raised an exception). If @code{e} 355 is @code{undefined} it is set to @code{BigFloatEnv.expBitsMax}. 356 357 @item precMin 358 Read-only integer. Return the minimum allowed precision. Must be at least 2. 359 360 @item precMax 361 Read-only integer. Return the maximum allowed precision. Must be at least 113. 362 363 @item expBitsMin 364 Read-only integer. Return the minimum allowed exponent size in 365 bits. Must be at least 3. 366 367 @item expBitsMax 368 Read-only integer. Return the maximum allowed exponent size in 369 bits. Must be at least 15. 370 371 @item RNDN 372 Read-only integer. Round to nearest, with ties to even rounding mode. 373 374 @item RNDZ 375 Read-only integer. Round to zero rounding mode. 376 377 @item RNDD 378 Read-only integer. Round to -Infinity rounding mode. 379 380 @item RNDU 381 Read-only integer. Round to +Infinity rounding mode. 382 383 @item RNDNA 384 Read-only integer. Round to nearest, with ties away from zero rounding mode. 385 386 @item RNDA 387 Read-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.} 390 Read-only integer. Faithful rounding mode. The result is 391 non-deterministically rounded to -Infinity or +Infinity. This rounding 392 mode usually gives a faster and deterministic running time for the 393 floating point operations. 394 395 @end table 396 397 @code{BigFloatEnv.prototype} properties: 398 399 @table @code 400 401 @item prec 402 Getter and setter (Integer). Return or set the precision in bits. 403 404 @item expBits 405 Getter and setter (Integer). Return or set the exponent size in bits 406 assuming an IEEE 754 representation. 407 408 @item rndMode 409 Getter and setter (Integer). Return or set the rounding mode. 410 411 @item subnormal 412 Getter and setter (Boolean). subnormal flag. It is false when 413 @code{expBits = expBitsMax}. 414 415 @item clearStatus() 416 Clear the status flags. 417 418 @item invalidOperation 419 @item divideByZero 420 @item overflow 421 @item underflow 422 @item inexact 423 Getter and setter (Boolean). Status flags. 424 425 @end table 426 427 @chapter BigDecimal 428 429 This extension adds the @code{BigDecimal} primitive type. The 430 @code{BigDecimal} type represents floating point numbers in base 431 10. It is inspired from the proposal available at 432 @url{https://github.com/littledan/proposal-bigdecimal}. 433 434 The @code{BigDecimal} floating point numbers are always normalized and 435 finite. There is no concept of @code{-0}, @code{Infinity} or 436 @code{NaN}. By default, all the computations are done with infinite 437 precision. 438 439 @section Operators 440 441 The following builtin operators support BigDecimal: 442 443 @table @code 444 445 @item + 446 @item - 447 @item * 448 Both operands must be BigDecimal. The result is computed with infinite 449 precision. 450 @item % 451 Both operands must be BigDecimal. The result is computed with infinite 452 precision. A range error is throws in case of division by zero. 453 454 @item / 455 Both operands must be BigDecimal. A range error is throws in case of 456 division by zero or if the result cannot be represented with infinite 457 precision (use @code{BigDecimal.div} to specify the rounding). 458 459 @item ** 460 Both operands must be BigDecimal. The exponent must be a positive 461 integer. The result is computed with infinite precision. 462 463 @item === 464 When one of the operand is a BigDecimal, return true if both operands 465 are a BigDecimal and if they are equal. 466 467 @item == 468 @item != 469 @item <= 470 @item >= 471 @item < 472 @item > 473 474 Numerical comparison. When one of the operand is not a BigDecimal, it is 475 converted to BigDecimal by using ToString(). Hence comparisons between 476 Number and BigDecimal do not use the exact mathematical value of the 477 Number value. 478 479 @end table 480 481 @section BigDecimal literals 482 483 BigDecimal 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 490 It returns @code{0m} if no parameter is provided. Otherwise the first 491 parameter is converted to a bigdecimal by using ToString(). Hence 492 Number values are not converted to their exact numerical value as 493 BigDecimal. 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) 506 Perform the specified floating point operation and round the floating 507 point result according to the rounding object @code{e}. If the 508 rounding object is not present, the operation is executed with 509 infinite precision. 510 511 For @code{div}, a @code{RangeError} exception is thrown in case of 512 division by zero or if the result cannot be represented with infinite 513 precision if no rounding object is present. 514 515 For @code{sqrt}, a range error is thrown if @code{a} is less than 516 zero. 517 518 The 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 523 be present to specify respectively the number of significant digits 524 (must be >= 1) or the number of digits after the decimal point (must 525 be >= 0). 526 527 @end table 528 529 @subsection Properties of the @code{BigDecimal.prototype} object 530 531 @table @code 532 @item valueOf() 533 Return the bigdecimal primitive value corresponding to @code{this}. 534 535 @item toString() 536 Convert @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") 541 Convert the BigDecimal @code{this} to string with the specified 542 precision @code{p}. There is no limit on the accepted precision 543 @code{p}. The rounding mode can be optionally 544 specified. @code{toPrecision} outputs either in decimal fixed notation 545 or in decimal exponential notation with a @code{p} digits of 546 precision. @code{toExponential} outputs in decimal exponential 547 notation with @code{p} digits after the decimal point. @code{toFixed} 548 outputs in decimal notation with @code{p} digits after the decimal 549 point. 550 551 @end table 552 553 @chapter Math mode 554 555 A new @emph{math mode} is enabled with the @code{"use math"} 556 directive. It propagates the same way as the @emph{strict mode}. It is 557 designed so that arbitrarily large integers and floating point numbers 558 are available by default. In order to minimize the number of changes 559 in the Javascript semantics, integers are represented either as Number 560 or BigInt depending on their magnitude. Floating point numbers are 561 always represented as BigFloat. 562 563 The 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