Introduction

This library implements arbitrary-precision arithmetic by scaling (shifting) arbitrary-precision integers. This is a rather simple solution that solves most problems with big numbers. Usually numbers is stored either in a fixed-point format, or in a floating-point format as a significand multiplied by an arbitrary exponent. The library has some additional support for converting floating-point numbers into fixed-point numbers. There are also some libraries for arbitrary-precision rational arithmetic, but this library support none of them.

In particular, this library does not implement IEEE 754r.

Representation

Numbers are represented during calculations as a significand that contains a sign and an integral part, and may also contain a decimal point and a fractional part. Withing Lua the “numbers” are stored inside closures that export its members as tables, and can also contain undefined “numbers”. It is not possible to use those for calculations. The exported API can use Lua numbers as arguments, and also raw strings.

Raw strings as arguments can be written in scientific notation and some engineering notations. The library does not support localized notation, but other functions may support this. Thus you might parse a localized number into a non-localized version, and then use that as a rwa string.

Examples on valid numbers as strings. These will be parsed and reformatted into a valid fixed-point format.

  • 123 – implicit plus sign
  • +123 – 'plus sign' (U+002B)
  • −123 - 'minus sign' (U+2212)
  • -123 - 'minus hyphen' (U+002D)
  • 123.456 – decimal point
  • 123 . 456 – adding spaces should not create problems
  • 123.456×10+789 – 'multiplication sign' (U+00D7)
  • 123.456×10⁷⁸⁹ – exponent with superscript digits, also superscript plus and minus
  • 123 . 456 × 10 + ⁷⁸⁹ – can mix ordinary plus-minus and superscript digits
  • 123.456e+789 – engineering notation
  • 123.456e⁷⁸⁹ – engineering notation with superscript
  • 123.456E789 – 'capital E' (Algol)
  • 123.456D789 – 'capital D' (FORTRAN, Sharp)
  • 123.456⏨789 – 'decimal exponent symbol' (Unicode)
  • 123.456&789 – 'ampersand' (Simula)
  • 123.456𝗘789 – 'mathematical sans-serif capital E' (Texas)
  • 123.456^789 – 'caret' (U+2038)

It is not quite clear whether only ordinary letters should be allowed, or all the mathematical variants. It is assumed that this falls into the category of localization.

Superscript can only be used for the exponent, and only after an exponent marker has been found. Other use of superscript or subscript is assumed to be outside the scope.

If a string (or number) fails to decode, then the value will become undefined, and later use of that number will fail.

Pitfalls

This describes some common pitfalls with the BCmath extension, the bcmath library, and the bc programming language.

Modulo operation

The modulo operation exists in several variants. In particular Lua uses floored division while Bc uses truncated division. For the most common situations, where both dividend and divisor is positive, the results are the same. Any use where dividend or divisor, or both, are negative might give discrepancies. This does not imply that any specific variant is wrong, they are just different.

False precision

Using arbitrary-precision arithmetic can easily lead to false precision. Numbers with a given precision can be combined, for example with addition or multiply, and accumulate more and more digits.

A simple example of addition

1.1?
0.01
1,1?

Do we really have two decimal places, or just one? The second decimal place in the first number is really unknown, and we can't really say what is more likely.

With multiply the problem gets more pronounced

1.2 × 1.2
   24
  12?
  144

The summation will then contain digits without sufficient certainty, unless the answer is rounded or otherwise truncated.

generated by LDoc TESTING