奇怪的战俘(x,y);行为

时间:2013-02-05 18:14:06

标签: c++ pow

在做作业的同时,我注意到一些非常奇怪的事情,我无法弄明白为什么。

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。

if()。

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

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

4 个答案:

答案 0 :(得分:10)

std::pow()返回一个浮点数。如果结果是例如24.99999999并且您将其转换为int,则会将其剪切为24

这就是你在第二个代码示例中所做的。
cout未转换为int并在第一个代码示例中输出正确的结果。

答案 1 :(得分:6)

'pow'返回一个double值,而不是int。当转换为int时,double值会被截断。

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

不建议将double与int进行比较。

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

对您的代码进行轻微编辑:

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

答案 2 :(得分:5)

pow function适用于floatdouble,而不是整数。将此值分配给整数时,该值可能会被截断,因为浮点数据的表示中存在精度问题。

我建议您阅读What Every Computer Scientist Should Know About Floating-Point Arithmetic,因为这会描述为什么您会看到此行为。

话虽如此,如果您使用double值而不是int,您可能会看到您期望的结果。

答案 3 :(得分:0)

pow()函数通常在数学库中实现,可能使用目标处理器中的特殊指令,对于x86,请参见How to: pow(real, real) in x86。但是,诸如fyl2xf2xm1之类的指令并不快,因此整个过程可能需要100个CPU周期。出于性能原因,像gcc这样的编译器提供“内置”函数,在特殊情况下提供strength reduction以更快地执行计算。当幂N是一个整数(如你的情况)和小(如你的情况)那么,乘以N次比调用库函数更快。

为了检测幂是整数的情况,数学库提供了重载函数,例如double pow(double,int)。你会发现gcc转换

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

内部进行2次乘法,这比库调用快得多,并且当两个操作数都是整数时给出精确的整数结果

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

为了获得这种强度减少,你应该

  1. 包括&lt; cmath&gt;

  2. 使用优化-O2
  3. 进行编译
  4. 明确调用库中的pow函数std::pow()以确保您获得的版本,而不是math.h中的版本
  5. 然后,您将匹配&lt;中的重载pow函数。 cmath&gt;看起来像这样

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

    请注意,此函数是使用__builtin_powi实现的,当函数是一个小整数时,它知道pow()到乘法的强度减少。