为什么这个浮动联合NaN的输出?

时间:2016-12-16 13:17:57

标签: c++ floating-point unions

在我的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。

测试代码:http://codepad.org/Q8ds1V0F

3 个答案:

答案 0 :(得分:6)

NaN 是正常的浮点值,您设置的字节被正确解释为a valid NaN

话虽如此,你可以得到输出“没有 spoon NaN”,因为using a union in this manner has undefined behaviour in C++。您只能在任何给定时间使用工会成员之一。它是不是重新解释的快捷方式!

答案 1 :(得分:6)

通过将所述字节写入数组,您将得到00 00 c0 7f的内存布局,其中7fc00000小写为0xFF。将此解释为endian会为您提供

  • 0的标志(正面,但与NaN无关)
  • 指数NaN
  • 尾数为0x400000(> 0,最高位设置→静音)

可以获得(无声)NaN值。

至少,这是C的重要性。在C ++中,它没有定义你做什么,但如果你得到<nav class="navbar navbar-dark bg-danger"> <a class="navbar-brand" href="#">Navbar</a> <button class="navbar-toggler hidden-lg-up float-xs-right" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation"></button> <div class="collapse navbar-toggleable-md" id="navbarResponsive"> <ul class="nav navbar-nav float-md-right"> <li class="nav-item active"> <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a> </li> <li class="nav-item"> <a class="nav-link" href="#">Link</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Link</a> </li> <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="http://example.com" id="responsiveNavbarDropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a> <div class="dropdown-menu" aria-labelledby="responsiveNavbarDropdown"> <a class="dropdown-item" href="#">Action</a> <a class="dropdown-item" href="#">Another action</a> <a class="dropdown-item" href="#">Something else here</a> </div> </li> </ul> </div> </nav> 结果,你的编译器会对它进行处理,如果它是C(不建议依赖它)关于未定义的行为!)。

答案 2 :(得分:0)

如果输出是不确定的,即无法确定其值,例如0/0,则通常会出现NaN(非数字)错误。

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

首先,浮点值基本上被分成比特字段,有很多比特保持尾数,所以许多比特拿着指数,一个拿着符号。另一方面,整数只是数字的base-2表示。他们的位不是一样的。

你可以这样做:

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