Skip to main content Skip to docs navigation

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.
On this page

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
fun String.bi(radix: Int): 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
fun BigInt.toString(radix: Int): 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
Was this article useful?