为什么这个浮点数联合体的输出是NaN?

4

在我的C++代码中,我声明了一个union:

typedef union U_FloatParse {
    float float_data;
    unsigned char byte_data[4];
} U_FloatConvert;

然后,我将byte_data数组的值设置为0、0、192、127:

U_FloatConvert depth_data;

depth_data.byte_data[0] = 0;
depth_data.byte_data[1] = 0;
depth_data.byte_data[2] = 192;
depth_data.byte_data[3] = 127;

printf("\n\nFloat = %f\n\n", depth_data.float_data);

作为输出结果我得到了NaN。为什么我没有得到一个正常的浮点值呢?当我传递值:56、137、33、63时,我得到了浮点值0.631000。
测试代码:http://codepad.org/Q8ds1V0F

5
在C或C++中,union的功能并非完全相同。 - Baum mit Augen
5
据我所知,在C++中没有定义这个东西。(如果您不是在问它们之间的差异,请只标记C和C++中的一个。) - molbdnilo
1
你了解IEEE浮点格式吗?你知道字节序吗? - Some programmer dude
3
当输入0x7fc00000时,预计会得到NaN,没有任何有趣的事情发生。 - harold
4
你原本期待得到什么价值? - molbdnilo
显示剩余3条评论
3个回答

7
通过将这些字节写入数组,您可以得到一个内存布局00 00 c0 7f,在小端endian中读取为7fc00000。将其解释为IEEE浮点数,您会得到:
  • 符号为0(正数,但NaN无关)
  • 指数为0xFF
  • 尾数为0x400000(> 0并且最高位设置→静默)
这将给您一个(静默)NaN值。
至少,在C中是这样的。在C ++中,未定义您要做什么,但如果您仍然获得NaN作为结果,则编译器会将其视为C(不建议依赖未定义的行为!)。

6

0

NaN(非数字)错误通常发生在输出不确定的情况下,即其值无法确定,例如0/0。

但我不会使用联合体(个人不喜欢它们),当您使用联合体时,设置一个成员并提取另一个成员是未定义的行为。

首先,浮点值基本上被分成位字段,其中有许多位用于保持尾数,许多位用于保持指数,而一位用于保持符号。另一方面,整数只是一个数字的二进制表示形式。它们的位只是没有排列相同。

您可以像这样做:

unsigned long int l = byte_data[0] | (byte_data[1] << 8) | (byte_data[2] << 16) | (byte_data[3] << 24);

1
你不能这样构建一个浮点数。 - harold
啊,显然……它必须是浮点数吗?^^ - Alen Hadzic
1
也许吧,我只是觉得用如何构建整数来回答这个问题有些奇怪,因为那并不是问题的实质。 - harold
没错。我本以为这行代码只是多余的,我的答案其实就是我写下的文字。对于造成的不便我很抱歉。我的意思是说,使用float,你将从字符数组中获得0x7fc00000,而你真正想要的是0x0000c07f,这是我试图解释的。 - Alen Hadzic

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