diff --git a/src/bigints.nim b/src/bigints.nim index 9ef5abb..21e0226 100644 --- a/src/bigints.nim +++ b/src/bigints.nim @@ -1,6 +1,6 @@ ## Arbitrary precision integers. -import std/[algorithm, bitops, math, options] +import std/[algorithm, bitops, fenv, math, options] type BigInt* = object @@ -1140,6 +1140,11 @@ func fastLog2*(a: BigInt): int = return -1 bitops.fastLog2(a.limbs[^1]) + 32*(a.limbs.high) +func toBiggestFloat*(x: BigInt): BiggestFloat = + let l = mantissaDigits(BiggestFloat)+1 + let shift = max(fastLog2(x) - l, 0) + let mantissa = BiggestFloat(toInt[BiggestInt](x shr shift).get()) + result = mantissa * pow(2.0, BiggestFloat(shift)) func invmod*(a, modulus: BigInt): BigInt = ## Compute the modular inverse of `a` modulo `modulus`. diff --git a/tests/tbigints.nim b/tests/tbigints.nim index 3b3a59d..d3f8be9 100644 --- a/tests/tbigints.nim +++ b/tests/tbigints.nim @@ -786,6 +786,16 @@ proc main() = doAssert pred(a, 3) == initBigInt(4) doAssert succ(a, 3) == initBigInt(10) + block: # to float + doAssert toBiggestFloat(initBigInt("0")) == 0.0 + doAssert toBiggestFloat(initBigInt("1")) == 1.0 + doAssert toBiggestFloat(initBigInt("-1")) == -1.0 + doAssert toBiggestFloat(initBigInt(BiggestInt.high)) == BiggestInt.high.toBiggestFloat + doAssert toBiggestFloat(initBigInt(BiggestInt.low)) == BiggestInt.low.toBiggestFloat + doAssert toBiggestFloat(initBigInt(BiggestInt.high) * initBigInt(4)) == BiggestInt.high.toBiggestFloat * 4.0 + doAssert toBiggestFloat(initBigInt(BiggestInt.low) * initBigInt(4)) == BiggestInt.low.toBiggestFloat * 4.0 + doAssert toBiggestFloat(initBigInt("17976931348623157") * initBigInt(10).pow(292)) == 17976931348623157e292 + static: main() main()