2010-11-28 120 views
8

我遇到了C#的问题。精确地使用Math.pow()。如果我尝试计算15^14,那么我会得到“29192926025390624”。但如果我用Wolfram Alpha计算,我会得到“29192926025390625”。正如你所看到的,唯一的区别就是1号码。 Wolfram Alpha是正确的。为什么不是C#?我如何解决这个问题,以便我可以在C#中获得正确的值?7Math.Pow计算不正确

我的代码相当简单,因为我只是尝试使用硬编码示例。所以我在做什么:Math.Pow(15,14);这给了29192926025390624。而不是“29192926025390625”这是正确的答案。

链接:Wolfram Alpha

+5

没有看到你的代码,任何事情都是猜测。我的猜测是Wolfram Alpha正在使用更高精度的浮点类型来计算它。 – ChrisF 2010-11-28 15:23:08

+4

顺便说一句,假设29192926025390625是正确的(它看起来是正确的:它以“5”结尾),那么Math.Pow按照规范行事:29192926025390624 **是最接近的双精度IEEE 754数字。其他附近的双精度数字是29192926025390628. – 2010-11-28 15:39:08

+0

它是正确计算;这是你对浮点算术的理解,以及`Math.Pow`的缺陷规范。享受:http://docs.sun.com/source/806-3568/ncg_goldberg.html – jason 2010-11-28 15:46:10

回答

9

Math.Pow浮点类型的工作,这是定义不准确的。如果您需要任意精度整数,请使用任意精度整数类型,如BigInteger结构。 BigInteger也有一个Pow方法。

+0

BigInteger.pow()做的伎俩(甚至ModPow)。非常感谢你。 – Ojtwist 2010-11-28 16:09:22

3

Math.Pow适用于双打。 Doubles are 64 bit floating point and have about 15-16 digits of precision in C#,因此,你所看到的是一个舍入误差。这就是浮点数的工作原理。

如果您需要更高精度,请尝试使用decimal。它是128位,并以10为基数。这可以准确地表示数字,最多28-29个有效数字。你可以很容易地定义你自己的Pow方法为十进制。

如果decimal是不够的,转向BigInteger,这是在.NET加入4.

4

Math.Pow作品上一倍。这与执行长得到正确的答案:

Func<long, int, long> power = null; 
power = (i, p) => p == 1 ? i : i*power(i, p - 1); 
Console.WriteLine(power(15, 14)); 
1

Math.Pow()与双数据类型 看到这个正常工作的问题。

 double i = 29192926025390625; 
     Console.WriteLine("{0}",i);//the result will be 29192926025390624.0 

哎呀对不起,通过断点检查值;在你的程序中;