[英]Floating point evaluation order in C
I am using Code::Blocks 10.05 on Windows 7. 我在Windows 7上使用Code :: Blocks 10.05。
I have compiled the following program, 我已经编译了以下程序,
#include<stdio.h>
int main()
{
float f=1.5;
printf("%f\n",(f-1)*1/2);
return 0;
}
The output was 0.250000 . 输出为0.250000 。 I understand it as follows, 我了解如下
Since f
is a float (f-1)
returns a float value of 0.500000 and the whole expression is upgraded to floating point arithmetic and hence 1/2 is also treated as float to get 0.500000 and hence the result. 由于f
是浮点数(f-1)
返回的浮点数为0.500000 ,整个表达式被升级为浮点算术,因此1/2也被视为浮点数,从而得到0.500000 ,从而得到结果。
Also the following statement, 还有下面的陈述,
float f=1.5;
printf("%f\n",1/2*(f-1));
gave 0.000000 as answer. 给出了0.000000作为答案。 Here the expression 1/2
performed integer division. 在这里,表达式1/2
执行整数除法。 Here I expected (f-1)
to be evaluated first and the whole expression to be upgraded to floating point arithmetic. 在这里,我希望首先评估(f-1)
并将整个表达式升级为浮点运算。
Here again I thought since the Polish notation is, 我再次想起,因为波兰记号是
* / 1 2 - f 1
division is the first operation performed and hence the result. 除法是执行的第一个操作,因此是结果。 Am I correct about this assumption? 我对这个假设是否正确?
Finally the following statement defies all the logic, 最后,以下语句违反了所有逻辑:
float f=1.5;
printf("%f\n",(f-1)*(1/2));
The output is 0.000000 , But here the Polish notation is, 输出为0.000000 ,但波兰符号为,
* - f 1 / 1 2
So (f-1)
ought to be evaluated first and hence the whole expression upgrades to floating point arithmetic and the output should be 0.250000 . 因此(f-1)
应该首先被求值,因此整个表达式将升级为浮点运算,并且输出应为0.250000 。
Where did I go wrong? 我哪里做错了? Does this have something to do with evaluation order of the operator *? 这与运算符*的评估顺序有关吗? Is the expression ambiguous in C? C语言中的表达是否模棱两可?
Since f is a float (f-1) returns a float value of 0.500000 and the whole expression is upgraded to floating point arithmetic 由于f是浮点数(f-1)返回的浮点值为0.500000且整个表达式被升级为浮点运算
No, where did you get that misinformation from? 不,您从哪里得到错误信息? Promotion to floating-point only applies to the one operator of which either operand is a floating-point number. 晋升为浮点数仅适用于其中一个操作数均为浮点数的一个运算符。 1/2
is not treated as a floating-point expression -- as such, it's not even evaluated. 1/2
不被视为浮点表达式-这样,甚至不对其进行求值。 Since multiplication and division have the same precedence and are left-associative, 由于乘法和除法的优先级相同,并且是左联想的,
(f - 1) * 1 / 2
is evaluated as 被评估为
((f - 1) * 1) / 2)
And there, 1
is promoted to float
(at least), and then because ((f - 1) * 1)
is floating-point as well, then the other operand of the division, 2
is also promoted to float
(or a higher precision FP number, depending on what the compiler wants). 并且,将1
提升为float
(至少),然后因为((f - 1) * 1)
也是浮点数,因此除法的另一个操作数也将2
提升为float
(或更高的float
精度FP编号,具体取决于编译器的要求)。
Here I expected (f-1) to be evaluated first and the whole expression to be upgraded to floating point arithmetic. 在这里,我希望首先评估(f-1)并将整个表达式升级为浮点运算。
No, that's an incorrect expectation, as I just explained. 不,正如我刚才解释的那样,这是一个错误的期望。 It's not the full expression that is subject to conversion to floating-point. 它不是要转换为浮点数的完整表达式。 It's only the other immediate operand of the operator of which the one operand is a float
. 它只是运算符的另一个立即操作数,其中一个操作数是float
。 Hence in the expression: 因此在表达式中:
(f - 1) * (1 / 2)
f - 1
is a float
. f - 1
是float
。 1 / 2
is an integer, it is zero, and then the integer zero is promoted to float
because the other operand of *
is a float
. 1 / 2
是一个整数,它是零,然后将整数零提升为float
因为*
的另一个操作数是float
。 The operands of /
, however, are integers, so the division is evaluated according to the rules of integer arithmetic. /
的操作数是整数,因此除法是根据整数算术规则进行的。
*
and /
have the same precedence, so (f-1)*1/2
is equivalent to ((f-1)*1)/2
, not what you think it is. *
和/
具有相同的优先级,因此(f-1)*1/2
等于((f-1)*1)/2
,而不是您认为的那样。
While 1/2*(f-1)
is equivalent to (1/2)*(f-1)
in which 1/2
has the value of 0
. 1/2*(f-1)
等于(1/2)*(f-1)
,其中1/2
的值为0
。
Because of the paranthesis: (1/2)
you only get a big zero (the result of 1/2) upgraded to a float. 由于偏瘫: (1/2)
您只会得到一个大的零(1/2的结果)升级为浮点数。 Hence the zero result. 因此结果为零。
(1/2)
is treated as integer and results zero. (1/2)
被视为整数,结果为零。 Multiplication by zero leads result which is also zero. 与零超前相乘的结果也为零。
The expression is evaluated from left to right: 该表达式从左到右求值:
f
is a float
. 表达式f
是float
。 f - 1
both operands are promoted to double
, the value is 0.5
. 在表达式f - 1
两个操作数都提升为double
,值是0.5
。 Call the expression E1
. 调用表达式E1
。 (f - 1) * 1
, which is E1 * 1
, both operands are promoted to double
and the value of the expression is 0.5
. 与(f - 1) * 1
,即E1 * 1
,两个操作数均提升为double
并且表达式的值为0.5
。 Call the expression E2
. 调用表达式E2
。 (f - 1) * 1 / 2
, which is E2 / 2
, both operands are promoted to double
and the value of th eexpression is 0.25
. 对于(f - 1) * 1 / 2
相同,即E2 / 2
,两个操作数均提升为double
,th表达的值为0.25
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.