2014-09-03 234 views
0
#include<stdio.h> 
#define MAX(a,b) ((a)>(b))?(a):(b) 
int main() 
{ 
    double a = 100 , b, c, e; 
    int d = -1;  
    b = 336; 
    c = -33.600000000000001; 
    e = a + (MAX(b, abs(c)) * d); 
    printf("max is %f", e); 
    return 0; 
} 

该程序的输出是436,而逻辑上它应该是-236。任何人都可以解释为什么这个程序的输出是变化的。输出意外

+0

将'fabs'用于浮点绝对值。 – 2014-09-03 07:50:33

回答

0
a + (MAX(b, abs(c)) * d); 

a + (MAX(b, abs(c)))*d; 
+1

我想解释一下这个不正确的行为,我在这个程序中做错了什么。 – user1492793 2014-09-03 07:53:26

+0

@ user1492793不调试它。使用一些额外的临时变量来简化你的复合表达式,这样你就可以看到printf或调试器出错的地方(调试101)。 – 2014-09-03 07:55:15

1

这是因为在逻辑上错宏扩展的:

(MAX(b, abs(c)) * d) =>(((b) > (abs(a))) ? (b) : (abs(a)) * d)

这里,(abs(a)) * d比三元算符优先更高。因此336= bMAX宏的输出)不乘以-1

此外,正如我所评论的,使用fabs()作为浮点绝对值。 abs()用于整数。

1
a + (MAX(b, abs(c)) * d); 
100 + (MAX(336, -33.6)*(-1)) 
100 + (((336)>abs(-33.6))?(336):abs(-33.6) * -1) /* Assuming fabs 33.6, may be 0 or other value otherwise */ 
100 + ((336>33.6)?336:-33.6) 
100 + 336 
436 
+0

abs(33.6)'= 33而不是33.6 – mch 2014-09-03 07:59:57

+0

@mch谢谢,更新 – 2014-09-03 08:00:47

2

宏替换后,a + (MAX(b, abs(c)) * d)变为:

a + (((b) > (abs(c))) ? (b) : (abs(c)) * d) 

注意*?:一个优先级数字,所以结果不是你所期望的。

正确的宏观应该是:

#define MAX(a,b) (((a)>(b))?(a):(b)) 
//    ^    ^

这是你应该避免可能的情况下使用宏的一个教训。因为编写正确的函数式宏很困难。

0
d = -1; 
b = 336; 
c = -33.600000000000001; 
e = a + (MAX(b, abs(c)) * d); 

当宏被评估变得

e = a + (((b)>(abs(c))) ? (b):((abs(c)) * d) 

这里(B)* d三元运算符之前被评估,因此三元运营商给出了答案336之后,d已被相乘,它不会改变为负数。