当你对一个浮点数进行逻辑非操作时会发生什么?

25

我认为这只会返回一个整数。我需要注意什么其他情况吗?C/C++之间有什么区别吗?

float a = 2.5;
!a; // What does this return? Int? Float?

2
可能的答案在这里:http://stackoverflow.com/questions/1969620/c-float-to-bool-conversion - cctan
3个回答

39
关于 C++,引用 C++11 §5.3.1/9:
逻辑非运算符的操作数被上下文转换为 bool 类型;如果转换后的操作数为 false,则其值为 true,否则为 false。结果的类型是 bool。
因此,这里真正相关的是 static_cast(some_float) 的行为,引用 §4.12/1:
算术、未加作用域的枚举、指针或指向成员的 prvalue 可以转换为类型为 bool 的 prvalue。零值、空指针值或空成员指针值转换为 false;任何其他值都转换为 true。std::nullptr_t 类型的 prvalue 可以转换为类型为 bool 的 prvalue;转换结果为 false。
将两者结合起来,2.5f 是一个非零值,因此将评估为 true,而当其取反时,将评估为 false,即 !a == false。
关于 C,引用 C99 §6.5.3.3/5:
逻辑非运算符的结果如果其操作数的值不等于 0,则其结果为 0;如果其操作数的值等于 0,则其结果为 1。结果的类型是 int。表达式 !E 等价于 (0==E)。
也就是说,与 C++ 相比,净结果相同,除了类型不同。

3
@NathanFig:没错,在 C 语言中,! 运算符的结果总是一个 int 类型。 - caf
@ildjarn,我看到您在F#编辑中使用了<!-- language: lang-ml -->来强制语法突出显示,但也有<!-- language: lang-f#-->,那么为什么不使用它呢? - Cetin Sert
1
@CetinSert:当我第一次开始使用SO时,只有前者起作用,我仅仅出于习惯继续使用它。:-] - ildjarn
1
@CetinSert:谢谢。:-]与某人联系的另一种选择是转到Chat.SO并创建一个新房间,然后转到该人的聊天资料并向他们发送邀请(它将向他们显示收件箱通知)。 - ildjarn
我想知道0.0是否可以被精确地表示,如果不能,则0.0 == 0.0将为false。(正如我们所知,我们不应直接比较两个浮点数值) - vacing
显示剩余2条评论

9

这里

如果一个float正好是0.0f,则转换为false,
如果不是0.0f,则也为true!
无穷大也将被转换为true。


2
我不确定无穷的否定,所以我在这里查看了输出http://ideone.com/WWoJB#view_edit_box - Rohit Vipin Mathews
如果+0.0f,-0.0f具有设置位并且反转后仍具有设置位,则返回已翻译的文本。 - old_timer
@dwelch 我不知道,我猜你每天都会学到新东西。 - cctan
我的理解是,您可以使符号位与指数和尾数仍显示为零。 - old_timer

-1

看看自己:

#include <iostream>

int main()
{
   float a = 2.5;

   if ( !a )
       std::cout << !a << "\n";

   else
       std::cout << !a << "\n";
}

10
“亲自看看”的问题在于您可能会观察到未定义或实现定义的行为,这只能告诉您在特定平台/编译器上发生了什么,而这在了解期望的明确定义行为方面是无用的。” - ildjarn
你不能从“实现定义”的行为中“期望”任何东西。那么对你来说,“良好定义”的意思是什么? - 01100110
9
没错,这就是为什么如果行为是实现定义的,“亲自看看”这个答案是无用的。谢谢你同意我的观点。:-P - ildjarn
3
你的 if/else 代码块的两个分支执行的操作完全相同,因此可以考虑不使用 if/else 语句。 - dreamlax

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接