奇怪POW(X,Y); 行为(Strange pow(x, y); behaviour)

2019-07-19 07:40发布

虽然做功课,我注意到一些奇怪的东西,我只是想不通为什么。

int x = 5;
cout << pow(x, 2);

其结果是25。这很好。 但是,如果我写相同的程序是这样的:

int x = 5;
int y = pow(x, 2);
cout << y;

其结果是24!

当x为2,3,4,6,7,8没有问题,但与5,10,11,13等的结果是1低于它应该是。

同样的事情,如果()。

for (int x = 1; x <= 20 ; x++) {
    if (x * x == pow(x, 2)) 
    cout << x << endl;
}

它打印出数字1,2,3,4,6,8,12,16。

Answer 1:

std::pow()返回一个浮点数。 如果结果是例如24.99999999和你投它来int ,它将被切断24

这就是你在第二个代码示例做什么。
cout不会转换到int并输出正确的结果在第一代码示例。



Answer 2:

“POW”返回一个双精度值,而不是一个int。 当投为int的双重价值被截断。

http://www.cplusplus.com/reference/cmath/pow/

不建议双到INT比较。

http://www.cplusplus.com/reference/cmath/pow/

为您的代码工作的小修改:

int x = 5;
double y = pow(x,2);   // correct datatype
cout << y;


Answer 3:

该战俘功能可与floatdouble ,不是整数。 当你将这个整数,该值可能会被截断,浮点数据,其表示有精度的问题。

我建议你阅读什么每台计算机科学家应该知道关于浮点运算 ,因为这说明为什么你看到此行为。

话虽这么说,如果你有工作double价值,而不是int ,你可能会看到您所期待的结果。



Answer 4:

战俘()函数的数学库通常实现的,可能使用目标处理器的特殊指令,用于x86看到如何:POW(真实的,真实的)在86 。 然而,如说明书fyl2xf2xm1并不快,所以整个事情可能需要100个CPU周期。 出于性能的考虑像GCC编译器提供“内置”功能,提供了强度降低到在特殊情况下更快地执行计算。 当电源N是一个整数(如您案)和小(如你的情况),那么它是更快繁殖N倍调用库函数。

为了检测其中功率是整数数学库提供重载函数,例如箱子double pow(double,int) 你会发现,GCC转换

double x = std::pow(y,4);

内部分为2次乘法,比库调用快得多,并给出了当两个操作数都是整数,你所期望的精确整数结果

double tmp = y * y;
double x = tmp * tmp;

为了得到这种类型的强度下降,你应该

  1. 包括<CMATH>

  2. 与优化编译-02
  3. 调用库中的战俘功能明确std::pow()以确保这就是你得到的版本,并从math.h中没有一个

然后,您将匹配它看起来像这样<CMATH>重载POW功能

inline double pow(double __x, int __i) { return __builtin_powi(__x, __i); }

请注意,此功能被实现__builtin_powi它知道POW()以相乘的强度降低时,功率是小的整数。



文章来源: Strange pow(x, y); behaviour
标签: c++ pow