I need to do some precision calcs with Big Numbers and I have been trying with Scala BigDecimal
but I have noted loss of precision.
As an example:
2^63 == 9223372036854775808
2^64 == 18446744073709551616
However when I do
println(BigDecimal.decimal(scala.math.pow(2, 63)).toBigIntExact())
println(BigDecimal.decimal(scala.math.pow(2, 64)).toBigIntExact())
I get
9223372036854776000 != 9223372036854775808
18446744073709552000 != 18446744073709551616
I don't know if I can get the exact BigInt
.
Maybe I have to take other approach.
Could anyone help me to fix this issue?
@ scala.math.pow(2, 63)
res0: Double = 9.223372036854776E18
You get Double
on math.pow
, and then you pass the result to BigDecimal
- it means that you lost precision even before you started using Big*
classes.
If you put numbers into BigDecimal
when they are still small and haven't yet lost precision (and if you use the constructors correctly) then you'll get the expected result:
@ BigDecimal(2).pow(63).toBigInt
res4: BigInt = 9223372036854775808
@ BigDecimal(2).pow(64).toBigInt
res5: BigInt = 18446744073709551616
@ BigDecimal(2).pow(63).toBigIntExact
res6: Option[BigInt] = Some(9223372036854775808)
@ BigDecimal(2).pow(64).toBigIntExact
res7: Option[BigInt] = Some(18446744073709551616)