Big Numbers

Package for dealing with Big Numbers both integral and decimal

Document not reviewed yet, might be outdated. Please, let us know if you find something invalid here.

https://github.com/korlibs/korge/tree/main/korge-foundation/src/common/korlibs/bignumber

General Bits

KBigNum exposes two basic classes: `BigInt` and `BigNum`. For them, you can construct ranges with: `BigIntRange`+`BigIntProgression` and `ClosedBigNumRange`

Basically you can do the typical operations you would do with `Int` or `Double`, but the precision is only limited by memory.

Also, they are much slower than their fixed-width counterparts.

In the case of JS, JVM & Android, BigInt wraps each native big integer implementation. There is also a `CommonBigInt` implementation, that is used in targets not providing a native BigInt implementation.

Have in mind that `CommonBigInt` has not been optimized, so the performance is subpar in some operations where some algorithms would provide a much better performance.

`BigInt`

This class allow to represent precise Big Integers that do not overflow.

Constructing `BigInt` instances

You can construct `BigInt` by using the `.bi` extensions:

``````val Long.bi: BigInt
val Int.bi: BigInt
val String.bi: BigInt
``````

In the case you want to use a different base other than decimal, you can use `String.bi(radix)`, where radix is the base you want to use: 2 for binary, 10 for decimal, 16 hexadecimal, etc.

Converting from `BigInt` to other types

You can convert the `BigInt` into an `Int`, a `BigInt` or a `String` by using some of these methods:

``````fun BigInt.toInt(): Int // Will throw [BigIntOverflowException] if the number cannot be represented as an [Int]
fun BigInt.toBigNum(): BigNum
fun BigInt.toString(): String
``````

Getting sign of the `BigInt`

You can determine the sign of the [BigInt] with these methods:

``````val BigInt.signum: Int // Returns -1, 0 or +1 depending on the sign of this [BigInt]
val BigInt.isZero: Boolean // Determines if this [BigInt] is 0
val BigInt.isNotZero: Boolean // Determines if this [BigInt] is not 0
val BigInt.isNegative: Boolean // Determines if this [BigInt] is negative
val BigInt.isPositive: Boolean // Determines if this [BigInt] is positive
val BigInt.isNegativeOrZero: Boolean // Determines if this [BigInt] is either negative or zero (non-positive)
val BigInt.isPositiveOrZero: Boolean // Determines if this [BigInt] is either positive or zero (non-negative)
``````

`BigInt` operations

You can perform typical unary arithmetic operations:

``````-(1.bi) == (-1).bi
+(1.bi) == (+1).bi
(-1).bi.abs() == (+1).bi
7.bi.square() == 49.bi
``````

And binary arithmetic operations:

``````(1.bi + 2.bi) == 3.bi
(1.bi - 2.bi) == (-1).bi
(2.bi * 3.bi) == 6.bi
(6.bi / 3.bi) == 2.bi
(9.bi % 5.bi) == 4.bi
(3.bi pow 100.bi) == "515377520732011331036461129765621272702107522001".bi
val (div, rem) = (97.bi divRem 17.bi)
``````

Also, you can do bit-wise operations:

``````// Bit combination
("0101".bi(2) and "0110".bi(2)).toString(2).padStart(4, '0') == "0100"
("0101".bi(2) or "0110".bi(2)).toString(2).padStart(4, '0') == "0111"
("0101".bi(2) xor "0110".bi(2)).toString(2).padStart(4, '0') == "0011"

// Bit shifting
("0101".bi(2) shl 2).toString(2).padStart(8, '0') == "00010100"
("0101".bi(2) shr 2).toString(2).padStart(8, '0') == "00000001"
``````

Constructing `BigInt` ranges and progressions

``````(10.bi)..(20.bi)
(10.bi..20.bi) step 2.bi
((10.bi..15.bi) step 2.bi).toList() == listOf(10.bi, 12.bi, 14.bi)
``````

BigNum

Constructing `BigNum` instances

You can construct `BigInt` instances by using the `.bn` extensions:

``````val Double.bn: BigNum
val Long.bn: BigNum
val Int.bn: BigNum
val String.bn: BigNum
``````

Adjusting `BigNum` number of decimals

In the case you want to have more (or less) decimals, you can adjust it with the `BigNum.convertToScale` extension.

``````fun BigNum.convertToScale(scale: Int): BigNum
``````

`BigNum` operations

The operations available to `BigNum` are much less reduced that the ones available to [BigInt].

You can do binary operations:

``````10.5.bn + 11.0.bn == "21.5".bn
10.5.bn - 11.0.bn == "0.5".bn
10.5.bn * 11.0.bn == "115.50".bn
10.5.bn / 11.0.bn == "0.9".bn
10.5.bn pow 4 == "12155.0625".bn
``````

In the case of the division, we might want to control the number of decimals we want to have:

``````10.5.bn.div(11.0.bn, 4) == "0.95454".bn
``````

Rounding `BigNum` to `BigInt`

``````fun BigNum.toBigInt(): BigInt
fun BigNum.toBigIntFloor(): BigInt
fun BigNum.toBigIntCeil(): BigInt
fun BigNum.toBigIntRound(): BigInt
``````

Getting `BigNum` decimal part:

``````"20.675".bn.decimalPart == "675".bi
``````

`BigNum` ranges

We can construct closed ranges the range `..` operator:

``````(10.4.bn in (10.5.bn .. 16.5.bn)) == false
``````