Different rounding between assignment and printf

I have a program with two variables of type int.

int num;
int other_num;

/* change the values of num and other_num with conditional increments */

printf ("result = %fn", (float) num / other_num);

float r = (float) num / other_num;
printf ("result = %fn", r);

The value written in the first printf is different from the value written by the second printf (by 0.000001, when printed with 6 decimal places).

Before the division, the values are:

num = 10201 
other_num = 2282

I've printed the resulting numbers to 15 decimal places. Those numbers diverge in the 7th decimal place which explains the difference in the 6th one.

Here are the numbers with 15 decimal places:

4.470201577563540
4.470201492309570

I'm aware of floating point rounding issues, but I was expecting the calculated result to be the same when performed in the assignment and in the printf argument.

Why is this expectation incorrect?

Thanks.


Probably because FLT_EVAL_METHOD is something other than 0 on your system.

In the first case, the expression (float) num / other_num has nominal type float , but is possibly evaluated at higher precision (if you're on x86, probably long double ). It's then converted to double for passing to printf .

In the second case, you assign the result to a variable of type float , which forces dropping of excess precision. The float is then promoted to double when passed to printf .

Of course without actual numbers, this is all just guesswork. If you want a more definitive answer, provide complete details on your problem.


The point is the actual position of the result of the expressions during the execution of the program. C values can live on the memory (which includes caches) or just on registers if the compiler decides that this kind of optimization is possible in the specific case.

In the first printf, the expression result is stored in a register, as the value is just used in the same C instruction, so the compiler thinks (correctly), that it would be useless to store it somewhere less volatile; as result, the value is stored as double or long double depending on the architecture.

In the second case, the compiler did not perform such optimization: the value is stored in a variable within the stack, which is memory, not register; the same value is therefore chopped at the 23th significant bit.

More examples are provided by streflop and its documentation.

链接地址: http://www.djcxy.com/p/90302.html

上一篇: C中的变量格式说明符

下一篇: 赋值和printf之间的舍入不同