简体   繁体   English

C中的浮点评估顺序

[英]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 - 1float 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: 该表达式从左到右求值:

  • The expression f is a float . 表达式ffloat
  • In the expression f - 1 both operands are promoted to double , the value is 0.5 . 在表达式f - 1两个操作数都提升为double ,值是0.5 Call the expression E1 . 调用表达式E1
  • Same for (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
  • Same for (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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM