我正在尝试进行pow(x, y)计算,其中x和y是无符号长整型,结果存储在无符号长整型中。这个结果会小于2^63,所以我应该能够做到。 但由于它返回一个浮点数,对于大数字我得到的结果不准确。有没有办法在不使用外部库(如bignum)的情况下获得精确的结果? 我知道我可以简单地将x*x乘以Y次,但这正是我想避免的,因为我想让我的程序更快。
10000^10000
比2^63大,但仍然可以轻松地放在网页上,尽管不是在注释中:一个后面跟着40000个0的1
。 - chqrlie10000^10
等于1e+40
。这是10³¹ Gb,对于一个网页来说有点太大了,而且讨论的数字比这还要大一倍的谷歌。 - Jongwareunsigned long long pow(unsigned long long x,unsigned int y) ...
是引起一些讨厌的错误的好方法。C语言没有为具有相同名称的函数提供签名。这掩盖了符合标准的 double pow( double, double );
函数。 - Andrew Henlepow
的定义本身就是不精确的。它使用 exp(y*log(x))
来模拟 x ^ y
。如果您想要完全的准确性,您需要使用外部库或者自己制作一个版本的 pow
。
我不确定你的代码。但是我猜你的代码应该像这样
unsigned long x,y;
x=...//
y=...//
unsigned long res=pow(x,y);
这不对。因为 pow() 总是返回 double 类型。
double pow(double x, double y)
这就是为什么你得到了双精度浮点数。
要获得正确的数字,您可以像这样操作:
unsigned long x,y;
x=...//
y=...//
unsigned long res=(unsigned long)pow(x,y);
#include <math.h>
正确声明了 pow
,第一种选项就没有问题,转换为 unsigned long
是隐式的,编译器将生成正确的代码。相反,如果没有声明 pow
,添加显式转换也不会改变任何东西:编译器将假定该函数具有 int pow(int,int);
原型,并且生成的代码将完全错误。 - chqrlie
pow
执行的是exp(y*log(x))
,速度较快但存在精度问题。 - Déjà vux
和y
的值足够小,或者意味着模算术?如果您将x
等于0
或1
进行测试,则最多应具有61次乘法,可以使用蛮力循环,甚至不值得优化。 - chqrlie