C中的浮点评估顺序

时间:2014-08-01 08:45:59

标签: c

我在Windows 7上使用Code :: Blocks 10.05。

我编写了以下程序,

#include<stdio.h>

int main()
{
 float f=1.5;
 printf("%f\n",(f-1)*1/2);
 return 0;
}

输出 0.250000 。 我理解如下,

由于f是浮点(f-1),因此返回浮点值 0.500000 ,整个表达式升级为浮点运算,因此 1/2 也被视为浮动,以获得 0.500000 ,从而得到结果。

还有以下声明,

 float f=1.5;
 printf("%f\n",1/2*(f-1));

0.000000 作为答案。 这里表达式1/2执行整数除法。在这里,我期望首先评估(f-1),并将整个表达式升级为浮点运算。

我再次想到,因为波兰语符号是,

* / 1 2 - f 1

除法是第一次执行的操作,因此是结果。 我对这个假设是否正确?

最后,以下陈述无视所有逻辑,

 float f=1.5;
 printf("%f\n",(f-1)*(1/2));

输出 0.000000 , 但这里的波兰表示法是,

* - f 1 / 1 2 

所以(f-1)应该首先进行评估,因此整个表达式升级为浮动 点算术和输出应 0.250000

我哪里出错了? 这是否与运营商的评估顺序有关*? C中的表达式是不明确的吗?

5 个答案:

答案 0 :(得分:6)

  

由于f是float(f-1),返回浮点值0.500000,整个表达式升级为浮点运算

不,你从哪里得到错误的信息?升级到浮点仅适用于其中任一操作数是浮点数的一个运算符。 1/2 被视为浮点表达式 - 因此,它甚至没有被评估。由于乘法和除法具有相同的优先级并且是左关联的,

(f - 1) * 1 / 2

评估为

((f - 1) * 1) / 2)

然后,1被提升为float(至少),然后因为((f - 1) * 1)也是浮点数,那么除法的另一个操作数{{1}也被提升为2(或更高精度的FP编号,具体取决于编译器的需要)。

  

这里我期望首先评估(f-1)并将整个表达式升级为浮点运算。

不,正如我刚才解释的那样,这是一个不正确的期望。它是要转换为浮点的完整表达式。它只是 运算符的另一个直接操作数,其中一个操作数是float。因此在表达式中:

float

(f - 1) * (1 / 2) f - 1float是一个整数,它为零,然后整数零被提升为1 / 2,因为float的另一个操作数是*。然而,float的操作数是整数,因此根据整数运算的规则来评估除法。

答案 1 :(得分:2)

*/具有相同的优先级,因此(f-1)*1/2相当于((f-1)*1)/2,而不是您的想法。

虽然1/2*(f-1)相当于(1/2)*(f-1),其中1/2的值为0

答案 2 :(得分:1)

由于paranthesis:(1/2)你只得到一个大的零(1/2的结果)升级到浮点数。因此零结果。

答案 3 :(得分:0)

(1/2)被视为整数,结果为零。乘以零导致结果也为零。

答案 4 :(得分:0)

表达式从左到右进行评估:

  • 表达式ffloat
  • 在表达式f - 1中,两个操作数都提升为double,值为0.5。调用表达式E1
  • (f - 1) * 1相同,即E1 * 1,两个操作数都提升为double,表达式的值为0.5。调用表达式E2
  • (f - 1) * 1 / 2相同,即E2 / 2,两个操作数都会提升为double,而且表达式的值为0.25