为什么这个 float union 的输出是 NaN?
Why is output of this float union NaN?
在我的 C++ 代码中,我声明了一个联合:
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。
NaN 是一个普通的浮点值,你设置的字节被正确解释为a valid NaN.
话虽如此,自 using a union in this manner has undefined behaviour in C++ 以来,您可以获得输出 "there is no spoon NaN"。您在任何给定时间只能使用工会的一名成员。它不是重新解释转换的捷径!
通过将上述字节写入数组,您将获得 00 00 c0 7f
的内存布局,在 endian, reads as 7fc00000
. Interpreting this as an IEEE float 中可以得到
- 0 的符号(正数,但与 NaN 无关)
0xFF
的指数
- 0x400000 的尾数(> 0 且设置了最高有效位 → 静默)
这会得到一个(无声的)NaN 值。
至少,这对 C 来说是重要的。在 C++ 中,它没有定义你做什么,但是如果你仍然得到 NaN
作为结果,你的编译器将它视为 C(尽管如此不推荐依赖未定义的行为!)。
如果输出不确定,即无法确定其值(例如 0/0),通常会出现 NaN(不是数字)错误。
但无论如何我不会使用联合(个人不喜欢),当你使用联合时,设置一个成员并提取另一个成员是未定义的行为。
一方面,浮点值基本上被分成位域,有那么多位保存尾数,那么多位保存指数,还有一位保存符号。另一方面,整数只是数字的 base-2 表示。他们的位只是排列不一样。
你可以这样做:
unsigned long int l = byte_data[0] | (byte_data[1] << 8) | (byte_data[2] << 16) | (byte_data[3] << 24);
在我的 C++ 代码中,我声明了一个联合:
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。
NaN 是一个普通的浮点值,你设置的字节被正确解释为a valid NaN.
话虽如此,自 using a union in this manner has undefined behaviour in C++ 以来,您可以获得输出 "there is no spoon NaN"。您在任何给定时间只能使用工会的一名成员。它不是重新解释转换的捷径!
通过将上述字节写入数组,您将获得 00 00 c0 7f
的内存布局,在 endian, reads as 7fc00000
. Interpreting this as an IEEE float 中可以得到
- 0 的符号(正数,但与 NaN 无关)
0xFF
的指数
- 0x400000 的尾数(> 0 且设置了最高有效位 → 静默)
这会得到一个(无声的)NaN 值。
至少,这对 C 来说是重要的。在 C++ 中,它没有定义你做什么,但是如果你仍然得到 NaN
作为结果,你的编译器将它视为 C(尽管如此不推荐依赖未定义的行为!)。
如果输出不确定,即无法确定其值(例如 0/0),通常会出现 NaN(不是数字)错误。
但无论如何我不会使用联合(个人不喜欢),当你使用联合时,设置一个成员并提取另一个成员是未定义的行为。
一方面,浮点值基本上被分成位域,有那么多位保存尾数,那么多位保存指数,还有一位保存符号。另一方面,整数只是数字的 base-2 表示。他们的位只是排列不一样。
你可以这样做:
unsigned long int l = byte_data[0] | (byte_data[1] << 8) | (byte_data[2] << 16) | (byte_data[3] << 24);