Unusual way out of pow

Following C code

int main(){ int n=10; int t1=pow(10,2); int t2=pow(n,2); int t3=2*pow(n,2); printf("%d\n",t1); printf("%d\n",t2); printf("%d\n",t3); return (0); } 

gives the following conclusion

 100 99 199 

I am using the devcpp compiler. That doesn't make any sense, does it? Any ideas? (This is pow (10,2) - it's something like 99,9999, does not explain the first conclusion. Moreover, I got the same conclusion, even if I include math.h)

+4
source share
3 answers

You are using a low-quality math library. A good math library returns accurate results for values ​​that are accurately represented.

As a rule, mathematical library routines should be approximations, since floating point formats cannot accurately represent exact mathematical results and because the calculation of various functions is difficult. However, for pow there are a limited number of results that are accurately presented, for example 10 2 . A good math library ensures that these results are returned correctly. The library you use cannot do this.

+6
source

Save calculation of results as double s. Print as double , using %f instead of %d . You will see that 99 really more like 99.999997 , and that should make more sense.

In general, when working with any floating point math, you should assume that the results will be approximate; that is, a little in any direction. Therefore, when you want to get accurate results - how you did it, you will have problems.

You should always understand the return type of functions before using them. See, for example, cplusplus.com :

 double pow (double base, double exponent); /* C90 */ 

From the other answers, I understand that there are situations where you can expect pow or other floating point math to be accurate. As soon as you understand the necessary inaccuracy, which will tell the math with floating point , consult with them.

+3
source

Your variables t1 , t2 and t3 must be of type double , because pow() returns double.


But if you want them to be of type int , use the round() function.

 int t1 = pow(10,2); int t2 = round(pow(n,2)); int t3 = 2 * round(pow(n,2)); 

It rounds the returned values 99.9... and 199.9... to 100.0 and 200.0 . And then t2 == 100 , because it is of type int , as well as t3 .

The output will be:

 100 100 200 

Since the round function returns an integer value, the one closest to x rounds half the cases from zero, regardless of the current rounding direction.


UPDATE: Here is a comment from math.h :

 /* Excess precision when using a 64-bit mantissa for FPU math ops can cause unexpected results with some of the MSVCRT math functions. For example, unless the function return value is stored (truncating to 53-bit mantissa), calls to pow with both x and y as integral values sometimes produce a non-integral result. ... */ 
+2
source

Source: https://habr.com/ru/post/1484455/


All Articles