【问题标题】:floating-point constant comparison - (0.0 ? 1 : 0)浮点常数比较 - (0.0 ? 1 : 0)
【发布时间】:2013-08-02 03:09:24
【问题描述】:

在下面的例子中,如果取消注释float f = 0.0;
并将return(0.0 ? 1 : 0); 替换为return(f ? 1 : 0);
输出为NIL

这是我的代码:

/* file main.c 
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86
cl -W4 -MTd -O2 -TC main.c -Fetest */   
#include <stdio.h>    
int my_func(void)
{
   /* float f = 0.0; */
   return(0.0 ? 1 : 0);
}
int main(void)
{  
    printf("%s\n", ( my_func() ? "ONE" : "NIL") );
    return 0;
}

在 32 位 Windows 机器上,使用 Visual Studio 输出此代码:

ONE
  • 为什么my_func() 返回值true (1)?
  • C 编译器如何解释这个表达式(0.0 ? 1 : 0)

【问题讨论】:

  • 这实际上是您面临的现实问题吗?这是您在实际代码中可能会做的事情吗? :-)
  • 我只是运行相同的代码并得到“NIL”
  • 只是在黑暗中拍摄——也许您的编译器正在比较十六进制值而不截断?前任。 (int) 0 等价于 0x000000,但使用浮点精度,你可能不会落在那个确切的值上
  • @Jim,无论内部表示是什么,0.0 转换为bool 时不应该总是变成false 吗?如果它是一个普通的整数转换,它应该被截断为0
  • @chux 我的错,搞混了。我今天看了太多代码。在有条件的情况下评估 0.0 应该与 0 进行比较,但同样,我不确定这是否取决于编译器(可能会或可能不会截断)

标签: c windows visual-studio floating-point


【解决方案1】:

这看起来像是 Microsoft 编译器中的一个错误,您应该将其提交给 Connect。我能够在 Visual Studio Express 2010 中复制它,但不能在 gcc 中复制:http://ideone.com/8qPRJd

计算结果为整数值0 的任何表达式都应等效于false。这正是它使用float 变量的方式,当我尝试使用double 时也是如此。

【讨论】:

  • 我同意。 (顺便说一句,我领先我 3 分钟)
  • 请注意,在 float_expr : expr1 : expr2 中不会发生到整数类型的转换。相反,条件表达式的第一个表达式需要具有标量类型,并与该类型的零进行比较(C11 中的 6.5.15:4)。 if (0.5) printf(…);确实打印(如果 (-0.0) printf(…); 不打印)。
  • 即使使用/Od,您也可以检查程序集列表...它直接删除了(0.0 ? 1 : 0) 并添加了mov eax, 1。我会说一个错误。在 if-expr 中放置文字 0.0 会导致生成适当的程序集(即使进行了优化)。
  • @user7116 我还能够验证 Visual Studio 2012 的工作方式相同,尽管我没有最新的服务包。
  • “任何计算结果为整数值 0 的表达式都应该等价于 false”——正确,但不完整。 比较等于 0 的任何表达式都是错误的。 0.0 不会计算为整数值 0(或任何其他整数值),但它确实等于 0。 (比较会将int0 转换为double。)
【解决方案2】:

return(0.0 ? 1:0) 编译成固定的return 1。另一种情况是浮点变量实际求值,0.0不等于0。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-14
    • 2021-07-10
    • 1970-01-01
    • 1970-01-01
    • 2012-05-13
    相关资源
    最近更新 更多