https://github.com/eobermuhlner/kotlin-big-math
Kotlin library for BigDecimal math functions (pow, sqrt, log, sin, ...) using arbitrary precision.
https://github.com/eobermuhlner/kotlin-big-math
bigdecimal kotlin mathematical-functions newton-raphson precision taylor-series
Last synced: 4 months ago
JSON representation
Kotlin library for BigDecimal math functions (pow, sqrt, log, sin, ...) using arbitrary precision.
- Host: GitHub
- URL: https://github.com/eobermuhlner/kotlin-big-math
- Owner: eobermuhlner
- License: mit
- Created: 2017-07-15T09:55:38.000Z (almost 9 years ago)
- Default Branch: master
- Last Pushed: 2020-06-22T14:29:43.000Z (about 6 years ago)
- Last Synced: 2023-07-28T00:15:20.567Z (almost 3 years ago)
- Topics: bigdecimal, kotlin, mathematical-functions, newton-raphson, precision, taylor-series
- Language: Kotlin
- Size: 74.2 KB
- Stars: 16
- Watchers: 5
- Forks: 2
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[](https://travis-ci.org/eobermuhlner/kotlin-big-math)
[](https://search.maven.org/artifact/ch.obermuhlner/kotlin-big-math)
# kotlin-big-math
Kotlin library for BigDecimal math functions (pow, sqrt, log, sin, ...) using arbitrary precision.
## Introduction
This library depends on the [big-math](https://github.com/eobermuhlner/big-math) library
and provides additional Kotlin features to do calculations with arbitrary precision.
It provides two different approaches to do the calculations
- `BigDecimal` + `DefaultBigDecimalMath` : recommended approach
- `BigFloat` : experimental approach
The [big-math](https://github.com/eobermuhlner/big-math) library
provides advanced math functions (`pow`, `sqrt`, `log`, `sin`, ...).
The `kotlin-big-math` library enhances the `big-math` library with the kotlin specific operators and infix methods.
Additionally it solves several of the problems that the standard kotlib library has when using `BigDecimal`.
# BigDecimal + DefaultBigDecimalMath
By using the following imports you can use the standard `BigDecimal` class
and the mathematical functions in `DefaultBigDecimalMath` in a simple but powerful manner:
```kotlin
import java.math.BigDecimal
import java.math.BigDecimal.*
import ch.obermuhlner.math.big.DefaultBigDecimalMath.*
import ch.obermuhlner.math.big.kotlin.bigdecimal.*
```
## BigDecimal Operators
* `+` operator
* `-` operator
* `*` operator
* `/` operator
* `%` operator
* `++` operator
* `--` operator
* `pow` infix method
* `root` infix method
* `valueOf(Int)` method (equivalent to `BigDecimal(Int)` constructor)
### Using BigDecimal + DefaultBigDecimalMath in Kotlin
The usage of `DefaultBigDecimalMath` follows the same rules as described in the [big-math](https://github.com/eobermuhlner/big-math#defaultbigdecimalmath) library.
To specify a temporary local `MathContext` you can either
use `createLocalMathContext()` method with `use`:
```kotlin
createLocalMathContext(10).use {
// do some calculations using DefaultBigDecimalMath
}
```
Alternatively you can use the `withLocalMathContext()` method
```kotlin
withLocalMathContext(10) {
// do some calculations using DefaultBigDecimalMath
}
```
Full example:
```kotlin
import java.math.BigDecimal
import java.math.BigDecimal.*
import ch.obermuhlner.math.big.DefaultBigDecimalMath.*
import ch.obermuhlner.math.big.kotlin.bigdecimal.*
fun main(args: Array) {
simpleExample()
createLocalMathContextExample()
withLocalMathContextExample()
piChudnovskyExample()
}
fun simpleExample() {
val v1 = valueOf(2) / 3
println(v1)
}
fun createLocalMathContextExample() {
println("Pi[default]: " + pi())
createLocalMathContext(5).use {
println("Pi[5]: " + pi())
createLocalMathContext(10).use {
println("Pi[10]: " + pi())
}
println("Pi[5]: " + pi())
}
println("Pi[default]: " + pi())
}
fun withLocalMathContextExample() {
println("Pi[default]: " + pi())
withLocalMathContext(5) {
println("Pi[5]: " + pi())
withLocalMathContext(10) {
println("Pi[10]: " + pi())
}
println("Pi[5]: " + pi())
}
println("Pi[default]: " + pi())
}
fun piChudnovskyExample() {
withLocalMathContext(100) {
println(piChudnovsky())
}
}
fun piChudnovsky() : BigDecimal {
val valueDivisor = (valueOf(640320) pow 3) / 24
var sumA = valueOf(1)
var sumB = valueOf(0)
var a = valueOf(1)
var dividendTerm1 = valueOf(5) // -(6*k - 5)
var dividendTerm2 = valueOf(-1) // 2*k - 1
var dividendTerm3 = valueOf(-1) // 6*k - 1
val precision = currentMathContext().precision
val iterationCount = (precision+13) / 14 + 1
for (k in 1 .. iterationCount) {
dividendTerm1 += -6
dividendTerm2 += 2
dividendTerm3 += 6
val dividend = dividendTerm1 * dividendTerm2 * dividendTerm3
val divisor = (valueOf(k) pow 3) * valueDivisor
a *= dividend / divisor
val b = a * k
sumA += a
sumB += b
}
val factor = sqrt(valueOf(10005)) * 426880;
val pi = factor / (sumA * 13591409 + sumB * 545140134);
return pi;
}
```
This produces the following output:
```
0.6666666666666666666666666666666667
Pi[default]: 3.141592653589793238462643383279503
Pi[5]: 3.1416
Pi[10]: 3.141592654
Pi[5]: 3.1416
Pi[default]: 3.141592653589793238462643383279503
Pi[default]: 3.141592653589793238462643383279503
Pi[5]: 3.1416
Pi[10]: 3.141592654
Pi[5]: 3.1416
Pi[default]: 3.141592653589793238462643383279503
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117069
```
# BigFloat
The `BigFloat` class is a wrapper around `BigDecimal` which simplifies the consistent usage of the `MathContext`
and provides a simpler API for calculations.
This is an experimental implementation.
Your mileage may vary.
Use the following imports:
```kotlin
import ch.obermuhlner.math.big.BigFloat
import ch.obermuhlner.math.big.BigFloat.*
import ch.obermuhlner.math.big.kotlin.bigfloat.*
```
## BigFloat Operators
* `+` operator
* `-` operator
* `*` operator
* `/` operator
* `++` operator
* `--` operator
* `pow` infix method
* `root` infix method
### Using BigFloat in Kotlin
The usage of `BigFloat` follows the same rules as described in the [big-math](https://github.com/eobermuhlner/big-math#bigfloat) library.
```kotlin
import ch.obermuhlner.math.big.BigFloat
import ch.obermuhlner.math.big.BigFloat.*
import ch.obermuhlner.math.big.kotlin.bigfloat.*
fun main(args: Array) {
simpleExample()
piExample()
}
fun simpleExample() {
val context = context(100)
val v1 = context.valueOf(2) / 3
println(v1)
}
fun piExample() {
println(piChudnovsky(100))
}
fun piChudnovsky(precision: Int) : BigFloat {
val context = context(precision + 10)
val valueDivisor = (context.valueOf(640320) pow 3) / 24
var sumA = context.valueOf(1)
var sumB = context.valueOf(0)
var a = context.valueOf(1)
var dividendTerm1 = context.valueOf(5) // -(6*k - 5)
var dividendTerm2 = context.valueOf(-1) // 2*k - 1
var dividendTerm3 = context.valueOf(-1) // 6*k - 1
val iterationCount = (context.getPrecision()+13) / 14 + 1
for (k in 1 .. iterationCount) {
dividendTerm1 += -6
dividendTerm2 += 2
dividendTerm3 += 6
val dividend = dividendTerm1 * dividendTerm2 * dividendTerm3
val divisor = (context.valueOf(k) pow 3) * valueDivisor
a *= dividend / divisor
val b = a * k
sumA += a
sumB += b
}
val factor = sqrt(context.valueOf(10005)) * 426880;
val pi = factor / (sumA * 13591409 + sumB * 545140134);
return context(precision).valueOf(pi);
}
```
This produces the following output:
```
0.6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068
```
## Comparison with standard kotlin library
The standard kotlin library already provides operators for `BigDecimal` but there are several problems with this solution.
### Standard Kotlin: Precision problem in division
The precision of the standard operators is determined from the arguments.
In the case of the division this can lead to unexpected results!
```kotlin
// Code example with standard kotlin library (without kotlin-big-math)
val v = valueOf(2) / valueOf(3)
println(v) // prints: 1 !!!
```
This problem is solved in `kotlin-big-math` because the precision is specified outside the function call.
```kotlin
// Code example with kotlin-big-math
val v = valueOf(2) / valueOf(3)
println(v) // prints: 0.6666666666666666666666666666666667
```
### Standard Kotlin: Missing `valueOf(Int)` function
The Java `BigDecimal` class has two overloaded `valueOf()` functions for the types `Double` and `Long` but not for `Int`.
```kotlin
// Code example with standard kotlin library (without kotlin-big-math)
val n = 2
val v0 = valueOf(n) // Compile Error!
```
This code does not compile but gives the following error:
```
Compile Error: None of the following functions can be called with the arguments supplied.
valueOf(Double) defined in java.math.BigDecimal
valueOf(Long) defined in java.math.BigDecimal
```
This problem is solved in `kotlin-big-math` by providing a `fun valueOf(Int): BigDecimal`.
```kotlin
// Code example with kotlin-big-math
val n = 2
val v = valueOf(n)
```
### Standard Kotlin: Missing overloaded operators for Int, Double, Long
The standard kotlin library does not provide overloaded operators for mixing `Int`, `Double`, `Long` with `BigDecimal`.
This leads to unnecessary clutter:
```kotlin
// Code example with standard kotlin library (without kotlin-big-math)
val v1 = valueOf(2)
val v2 = v1 * valueOf(3)
val v3 = valueOf(4) * v1
```
This problem is solved in `kotlin-big-math` by providing a overloaded operators where one argument is `Int`, `Double` or `Long`.
```kotlin
// Code example with kotlin-big-math
val v1 = valueOf(2)
val v2 = v1 * 3
val v3 = 4.0 * v1
```
## Using kotlin-big-math in your projects
To use the kotlin library you can either download the newest version of the .jar file from the
[published releases on Github](https://github.com/eobermuhlner/kotlin-big-math/releases/)
or use the following dependency to
[Maven Central](https://search.maven.org/#search%7Cga%7C1%7Ckotlin-big-math)
in your build script (please verify the version number to be the newest release):
### Use kotlin-big-math in Maven Build
```xml
ch.obermuhlner
kotlin-big-math
2.3.0
```
### Use kotlin-big-math in Gradle Build
```gradle
repositories {
mavenCentral()
}
dependencies {
compile 'ch.obermuhlner:kotlin-big-math:2.3.0'
}
```