I'll provide another answer that is hopefully more clear. The point is: Since the precision of System.Double
is limited to approx. 15-17 decimal digits, the result of any Pow(BigInteger, Double)
calculation will have an even more limited precision. Therefore, there's no hope of doing better than carlosfigueira's answer does.
Let me illustrate this with an example. Suppose we wanted to calculate
Pow(10, exponent)
where in this example I choose for exponent
the double-precision number
const double exponent = 100.0 * Math.PI;
This is of course only an example. The value of exponent
, in decimal, can be given as one of
314.159265358979
314.15926535897933
314.1592653589793258106510620564222335815429687500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000...
The first of these numbers is what you normally see (15 digits). The second version is produced with exponent.ToString("R")
and contains 17 digits. Note that the precision of Double
is less than 17 digits. The third representation above is the theoretical "exact" value of exponent
. Note that this differs, of course, from the mathematical number 100π near the 17th digit.
To figure out what Pow(10, exponent)
ought to be, I simply did BigInteger.Log10(x)
on a lot of numbers x
to see how I could reproduce exponent
. So the results presented here simply reflect the .NET Framework's implementation of BigInteger.Log10
.
It turns out that any BigInteger x
from
0x0C3F859904635FC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
through
0x0C3F85990481FE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
makes Log10(x)
equal to exponent
to the precision of 15 digits. Similarly, any number from
0x0C3F8599047BDEC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
through
0x0C3F8599047D667FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
satisfies Log10(x) == exponent
to the precision of Double
. Put in another way, any number from the latter range is equally "correct" as the result of Pow(10, exponent)
, simply because the precision of exponent
is so limited.
(Interlude: The bunches of 0
s and F
s reveal that .NET's implementation only considers the most significant bytes of x
. They don't care to do better, precisely because the Double
type has this limited precision.)
Now, the only reason to introduce third-party software, would be if you insist that exponent
is to be interpreted as the third of the decimal numbers given above. (It's really a miracle that the Double
type allowed you to specify exactly the number you wanted, huh?) In that case, the result of Pow(10, exponent)
would be an irrational (but algebraic) number with a tail of never-repeating decimals. It couldn't fit in an integer without rounding/truncating. PS! If we take the exponent to be the real number 100π, the result, mathematically, would be different: some transcendental number, I suspect.