忽略我为什么要这样做,754 IEEE fp标准没有定义以下行为:
float h = NAN;
printf("%x %d\n", (int)h, (int)h);
Gives: 80000000 -2147483648
基本上,无论我给出的NAN值是多少,它都输出80000000(十六进制)或-2147483648(十进制)。是否有这样的原因和/或这是正确的行为?如果是这样,怎么回事?
我给它不同的NaN值的方式如下: How can I manually set the bit value of a float that equates to NaN?
基本上,是否存在NaN的有效负载影响演员输出的情况?
谢谢!
答案 0 :(得分:11)
对于不在整数变量范围内的值(截断值为±1),未定义浮点数转换为整数的结果。
NaN
超出范围,因此结果未定义。
实际上,该标准仅提到将浮点类型的有限值转换为整数类型。
答案 1 :(得分:9)
这种行为是有原因的,但通常不应该依赖它。
正如您所注意到的,IEEE-754没有指定将浮点NaN转换为整数时会发生什么,除了它应该引发无效的操作异常,编译器可能会忽略该异常。 C标准说行为是未定义的,这意味着你不仅不知道你将得到什么整数结果,你不知道你的程序将做什么;该标准允许程序中止或获得疯狂的结果或做任何事情。您可能在英特尔处理器上执行了此程序,并且您的编译器可能使用其中一个内置指令进行了转换。英特尔非常谨慎地指定指令行为,并且将浮点NaN转换为32位整数的行为是返回0x80000000,而不管NaN的有效负载,这是您观察到的。
因为Intel指定了指令行为,所以如果您知道所使用的指令,则可以依赖它。但是,由于编译器不向您提供此类保证,因此您不能依赖此指令。
答案 2 :(得分:2)
首先,NAN是根据IEEE标准不被视为浮点数的所有内容。 所以它可以是几件事。在我使用的编译器中有NAN和-NAN,所以它不仅仅是一个值。
其次,每个编译器都有isnan
个函数集来测试这种情况,因此程序员不必自己处理这些位。总而言之,我认为偷看这个价值并没有任何区别。您可能会查看其值以查看其IEEE构造,如符号,尾数和指数,但同样,每个编译器都会提供自己的函数(或更好的说,库)来处理它。
然而,我对你的测试还有更多的话要说。
float h = NAN;
printf("%x %d\n", (int)h, (int)h);
你做的转换将浮动用于将其转换为int。如果你想得到 由float表示的整数,执行以下操作
printf("%x %d\n", *(int *)&h, *(int *)&h);
也就是说,你获取float的地址,然后将它作为指向int的指针引用,并最终获取int值。这样就可以保留位表示。