Strange pow (x, y); behavior

During my homework, I noticed something really strange that I just can’t understand why.

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

Result 25. This is wonderful. But if I write the same program like this:

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

The result is 24!

When x is 2, 3, 4, 6, 7, 8 without problems, but with a result of 5, 10, 11, 13, etc. the result is 1 lower than it should be.

Same thing with if ().

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

It prints numbers 1, 2, 3, 4, 6, 8, 12, 16.

+4
source share
4 answers

std::pow() returns a floating point number. If the result is, for example, 24.99999999 , and you added it to an int , it will be disabled to 24 .

And this is what you do in the second code example.
cout not converted to int and displays the correct result in the 1st code example.

+10
source

'pow' returns a double value, not int. A double value is truncated when converted as an int.

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

Comparing double with int is not recommended.

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

Minor editing of your code:

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

The pow function works with float and double , not integers. When you assign this to an integer, the value may be truncated, since floating point data has problems with precision in the representation.

I recommend reading What Every Computer Scientist Should Know About Floating-Point Arithmetic , as It Describes Why You See This Behavior.

If you work with double values ​​instead of int , you will most likely see the expected results.

+5
source

The pow () function is usually implemented in the math library, possibly using special instructions in the target processor, for x86 see How: pow (real, real) in x86 . However, instructions like fyl2x and f2xm1 are not fast, so all this can take 100 CPU cycles. For performance reasons, a compiler such as gcc provides “built-in” functions that provide a reduction in strength to enable faster calculations in special cases. When power N is an integer (as in your case) and small (as in your case), it’s faster to multiply N times than by calling a library function.

To detect cases where power is an integer, the math library provides overloaded functions, such as double pow(double,int) . You will see that gcc converts

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

internally in 2 multiplications, which is much faster than calling the library, and gives the exact integer result you would expect when both operands are integers

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

to get this kind of power reduction you have to

  • include <cmath>

  • compile with -O2 optimization
  • call the pow function in the library explicitly std::pow() to make sure you get the version, not one of math.h

Then you will correspond to the pow overloaded function in <cmath>, which looks like this

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

Note that this function is implemented using __builtin_powi , which knows the decrease in the power of pow () to multiply when the power is a small integer.

0
source

All Articles