将无穷大指定为浮动

我正在尝试将浮点数初始化为无穷大值,而不使用INFINITY宏。

float f[] = { 0b01111111100000000000000000000000, // 0x7f800000 0x7f800000 -1, 0x7f800000 -2, 0x7f800000 -64, 0x7f800000 -65 }; 

印刷:

 2139095040.000000 2139095040.000000 2139095040.000000 2139095040.000000 2139094912.000000 

为什么不是第一个数据无穷大(如1 / 0.0 )而其他数据在最后一个数据之前不会改变?

0x7f7fffff应该是浮点数的最大值,并尝试0x7f80000被认为是无穷大。

你的问题的原因是符号:

  • 0x7f800000
  • 0b01111111100000000000000000000000

这种符号与int类型有关,当你将int float它意味着从intfloat implicit conversion 。 在这种情况下,您的两个数字都是2139095040 (十进制),它将被转换为float型。

要避免此问题,您可以在4个字节的精确位位置分配值。 这里有几个例子。

 float f; *(int*)&f = 0x7f800000; 

或者你可以使用工会

 union u_fi { float f; int i; } fi; fi.i = 0x7f800000; 

但使用这两种解决方案时要小心。 当int在第一种情况下超过4个字节时它将不能安全地工作,并且当intbig-endian时它根本不起作用。 所以这个解决方案依赖于平台,我建议使用如下所示的宏。

你的问题的另一个解决方案是使用非常大量的转换为floatinf 。 为此,您可以在使用宏

 #define _HUGE_ENUF 1e+300 #define INFINITY ((float)(_HUGE_ENUF * _HUGE_ENUF)) float f = INFINITY; 

您可以使用宏HUGE_VAL。 或者,如果您愿意,可以将虚拟变量初始化为零,并除以该变量(因此您不会收到编译错误)。

假设您正在使用IEEE754(您的问题暗示),您可以给出溢出的结果。 float只能代表最高3.4028235f38值,所以我们可以使用

 float x = 1e20f*1e20f; 

根据您的系统/编译器,您可能需要指定标志(例如c99c11将起作用),以便x显式地转换为float并且不作为更高的中间精度存储。