Tips and tricks #9: Big numbers

How to use big number input and PCR library.

Tips and tricks series

This article may rely on knowledge you should get from previous articles, so you may want to check them first.

Browser JavaScript implementation has a limit of integer number exact representation: 9007199254740991 or 253-1 or roughly 9 quadrillion. To overcome this limit big number libraries can be applied.
To work with big numbers PLANETCALC has a special input set: Big number and Big number array. The big number library underlying these inputs supports operations in an integer field, complex integer fields, and real, rational, or complex fractional ring. General Number output can be used to represent this library calculation results. The library is globally available in a calculator source code by PCR. prefix.
This library is internally based on big-integer library, which has a good performance, but PCR library was designed in idea to have a usable interface, the same overall supported fields \mathbb{Z},\mathbb{R},\mathbb{Q},\mathbb{C} rather than performance. So consider using the bigInt library directly, if your calculator requires the best performance. The Number output supports bigInt types as well.

The calculator below uses Big number input, Number output, and PCR library to calculate GCD using extended Euclidean algorithm:

PLANETCALC, Extended Euclidean algorithm

Extended Euclidean algorithm

Greatest Common Divisor
 
Coefficient for bigger integer
 
Coefficient for smaller integer
 

PCR big number library overview by the Euclidean algorithm code example

The calculator has two big integer inputs, defined in the calculator editor as shown in the picture below:

Big number parameter definition
Big number parameter definition

So first and second input variables are defined as PCR.integer by input editor. You may also define PCR numbers variables in code, see the calculator code fragment, which defines a placeholder for the result with three PCR integers:

var euklid = {
    gcd: PCR.integer(1),
    x: PCR.integer(0),
    y: PCR.integer(0)
};

PCR integers has a number of arithmetic operations. The code below demonstrates some of them (integer division: divmod, subtraction: sub and multiplication: mul).

function gcd (a, b, holder) {
    if (a.eq(0) ) {
        holder.x = PCR.integer(0); 
        holder.y = PCR.integer(1);
        return b;
    }
    var q = b.divmod( a );
    var d = gcd (q.r, a, holder);
    var tx = holder.x;
    holder.x = holder.y.sub( 
        q.q.mul( holder.x ) );
    holder.y = tx;
    return d;
}

Besides arithmetics, PCR library has a number of compare operations defined over all PCR number types. The code fragment below demonstrates greater than (gt) operation:

euklid.gcd =gcd(first.gt( second ) ? 
second : first, first.gt( second ) 
? first : second, euklid);

To report the result to users just SetValue to a general Number output:

res.SetValue(euklid.gcd);
coef1.SetValue(euklid.y);
coef2.SetValue(euklid.x);

The Number output can be configured to display either real or rational numbers. The rational numbers mode output having PCR big number value can be used for the precise number representation as a simple fraction. See the Result set switch on the following picture:

Numeric output field editor
Numeric output field editor

PCR big number library reference

Initialization

Function Example Description
PCR.integer var one = PCR.integer(1); Big integer number definition
PCR.rational var quarter = PCR.rational(1,4); Rational number definition
PCR.complex var complex = PCR.complex(7,3); //7+3i Complex number definition
PCR.real var real = PCR.real(3.1415926); Real number definition
PCR.parse var complexFraction = PCR.parse("1/3+i"); Parses a string into PCR number.

Operations

Function Example Description
add var two = PCR.integer(1).add(1); Adds two PCR numbers.
sub var twoThird = PCR.integer(1).sub(PCR.rational(1,3)); Subtract two PCR numbers
neg var minusOne = PCR.integer(1).neg(); Negates a PCR number
mul var complex = PCR.complex(7,3).mul(2); //14+6i Multiply two PCR numbers
div var quarter = PCR.rational(1,2).div(2); Divide two PCR numbers
divmod var twoAndOne = PCR.integer(5).div(2); // returns {q:2,r:1} Integer division with modulo
mod var one = PCR.integer(5).mod(2); Integer division modulo
idiv var two = PCR.integer(5).idiv(2); Integer division
abs var one = PCR.integer(-1).abs(); Absolute value
gcd var two = PCR.integer(6).gcd(8); Greatest common divisor

Conversions

Function Example Description
toString var fraction = PCR.rational(1/3).toString(); // returns "1/3" Converts PCR number into string.
toFixed var fraction = PCR.rational(1/3).toFixed(2); // returns "0.33" Floating point string representation with fixed decimal digits.
toTeX var fraction = PCR.rational(1/3).toTeX(); // returns "\frac{1}{3}" LaTeX representation.

Comparsions

Function Example Description
isZero var zero = PCR.rational(1/2).sub(0.5).isZero(); Compare a PCR number with zero.
compare var greater = PCR.rational(1/2).compare(0.3); Compare two values, returns 1 if the left operand is greater, returns -1 - if the left operand is less, and 0 - if both operands are equal .
eq var equal = PCR.rational(1/2).eq(0.5); Equality.
gt var greater = PCR.rational(1/2).gt(0.3); Greater than.
gte var greater = PCR.rational(1/2).gte(0.3); Greater than or equal.
lt var greater = PCR.rational(1/2).lt(0.3); Less than.
lte var greater = PCR.rational(1/2).lte(0.3); Less than or equal.
URL 复制到剪贴板
PLANETCALC, Tips and tricks #9: Big numbers

评论