我尝试使用 BigInteger.Pow
方法来计算类似于10^12345.987654321的数,但是这个方法只接受像这样的整数作为指数:
BigInteger.Pow(BigInteger x, int y)
那么我该如何在上述方法中使用双精度浮点数作为指数呢?
我尝试使用 BigInteger.Pow
方法来计算类似于10^12345.987654321的数,但是这个方法只接受像这样的整数作为指数:
BigInteger.Pow(BigInteger x, int y)
那么我该如何在上述方法中使用双精度浮点数作为指数呢?
C#中没有任意精度的大数支持,因此无法直接完成此操作。有一些替代方案(例如寻找第三方库),或者您可以尝试像下面的代码一样做 - 如果基数足够小,就像在您的情况下。
public class StackOverflow_11179289
{
public static void Test()
{
int @base = 10;
double exp = 12345.123;
int intExp = (int)Math.Floor(exp);
double fracExp = exp - intExp;
BigInteger temp = BigInteger.Pow(@base, intExp);
double temp2 = Math.Pow(@base, fracExp);
int fractionBitsForDouble = 52;
for (int i = 0; i < fractionBitsForDouble; i++)
{
temp = BigInteger.Divide(temp, 2);
temp2 *= 2;
}
BigInteger result = BigInteger.Multiply(temp, (BigInteger)temp2);
Console.WriteLine(result);
}
}
a ^ (int + frac) = a ^ int * a ^ frac
Pow(10, exponent)
const double exponent = 100.0 * Math.PI;
这当然只是一个例子。 exponent
的值,以十进制表示,可以给定为以下之一
314.159265358979
314.15926535897933
314.1592653589793258106510620564222335815429687500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000...
这些数字中的第一个是你通常看到的(15位数)。第二个版本是使用exponent.ToString("R")
生成的,包含17位数。请注意,Double
的精度小于17位数。上面的第三种表示是exponent
的理论“精确”值。当然,这与数学上的100π在第17位数上有所不同。
为了弄清楚Pow(10, exponent)
应该是什么,我只需对许多数字x
执行BigInteger.Log10(x)
,以查看如何重现exponent
。因此,这里呈现的结果仅反映了.NET Framework对BigInteger.Log10
的实现。
事实证明,任何BigInteger x
都可以从
0x0C3F859904635FC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
through
0x0C3F85990481FE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
Log10(x)
函数将以15位精度使其等于exponent
。同样,任何数字从
0x0C3F8599047BDEC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
through
0x0C3F8599047D667FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
满足 Log10(x) == exponent
的精度为 Double
。换句话说,后者范围内的任何数字都同样“正确”作为 Pow(10, exponent)
的结果,仅因为 exponent
的精度非常有限。
(插曲:一堆 0
和 F
表明 .NET 的实现只考虑了 x
的最高有效字节。他们不关心做得更好,正是因为 Double
类型具有这种有限的精度。)
现在,引入第三方软件的唯一原因是,如果您坚持认为exponent
应该被解释为上述十进制数的第三个数字。(真是一个奇迹,Double
类型允许您精确地指定您想要的数字,对吧?)在这种情况下,Pow(10, exponent)
的结果将是一个带有永不重复小数尾巴的无理(但代数)数字。它不能在没有四舍五入/截断的情况下适合一个整数。另外,如果我们将指数取为实数 100π,则数学上的结果将有所不同:我猜会得到某些超越数。
new BigInteger(Math.Pow(10, 123.123));
不正确? - Sebastian PiuDouble
和BigInteger
。然后将temp
除以这个常量一次,将temp2
乘以这个常量一次即可。 - Jeppe Stig Nielsen