Reputation: 19002
using System.Numerics;
double doubleNumber = Math.Pow(1000, 99); // = 1.0E+297
BigInteger bigBase = (BigInteger)bigNumber; // = 1000000000000000017652801462756379714374878780719864776839443139119744823869255243069012222883470359078822072829219411228534934402712624705615450492327979456500795456339201761949451160807447294527656222743617592048849967890105831362861792425329827928397252374398383022243308510390698430058459037696
Why is the BigInteger
value not just 1 kagillion (1,000 followed by a bagillion 0's)?
Upvotes: 0
Views: 432
Reputation: 391476
System.Double
only has 15 decimal digits of precision, which means the value will be close to the actual value, but might not be precise.
It all has to do with how floating point values are encoded in order to occupy a fixed amount of memory.
This is exactly the same problem which lets 1.0
end up as 0.999999999999999999etc
.
If you need absolute precision, you need to use a library/type which has that, double
has not.
For your specific code, you might want to do this:
BigInteger bigBase = BigInteger.Pow(1000, 99);
Upvotes: 4
Reputation: 1149
The implementation of BigInteger uses a lot of bit shifting, so when you convert a double to a BigInteger, the double representation has a finite set of bits (64 bits in for a double), so not all the bits are there to accurately represent the value.
Instead of using Math.Pow, you should be using
var bigBase = BigInteger.Pow(1000, 99);
Also, explicitly casting a numeric type to a BigInteger is the same as using the BigInteger constructor:
var bigBase = (BigInteger)doubleNumber;
Is equivalent to:
var bigBase = new BigInteger(doubleNumber);
Upvotes: 1