问题
The 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 output
100
99
199
I am using a devcpp compiler. It does not make any sense, right? Any ideas? (That pow(10,2) is maybe something like 99.9999 does not explain the first output. Moreover, I got the same output even if I include math.h)
回答1:
You are using a poor-quality math library. A good math library returns exact results for values that are exactly representable.
Generally, math library routines must be approximations both because floating-point formats cannot exactly represent the exact mathematical results and because computing the various functions is difficult. However, for pow
, there are a limited number of results that are exactly representable, such as 102. A good math library will ensure that these results are returned correctly. The library you are using fails to do that.
回答2:
Store the result computations as double
s. Print as double
, using %f
instead of %d
. You will see that the 99
is really more like 99.999997
, and this should make more sense.
In general, when working with any floating point math, you should assume results will be approximate; that is, a little off in either direction. So when you want exact results - like you did here - you're going to have trouble.
You should always understand the return type of functions before you use them. See, e.g. cplusplus.com:
double pow (double base, double exponent); /* C90 */
From other answers I understand there are situations when you can expect pow
or other floating-point math to be precise. Once you understand the necessary imprecision that plagues floating point math, please consult these.
回答3:
Your variables t1
, t2
and t3
must be of type double
because pow()
returns double.
But if you do want them to be of type int
, use 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
and so does t3
.
The output will be:
100
100
200
Because the round
function returns the integer value nearest to x rounding half-way cases away from zero, regardless of the current rounding direction.
UPDATE: Here is 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. ... */
来源:https://stackoverflow.com/questions/16923249/unusual-output-from-pow