将无穷大指定为浮动
我正在尝试将浮点数初始化为无穷大值,而不使用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
它意味着从int
到float
implicit conversion
。 在这种情况下,您的两个数字都是2139095040
(十进制),它将被转换为float
型。
要避免此问题,您可以在4个字节的精确位位置分配值。 这里有几个例子。
float f; *(int*)&f = 0x7f800000;
或者你可以使用工会
union u_fi { float f; int i; } fi; fi.i = 0x7f800000;
但使用这两种解决方案时要小心。 当int
在第一种情况下超过4个字节时它将不能安全地工作,并且当int
是big-endian
时它根本不起作用。 所以这个解决方案依赖于平台,我建议使用如下所示的宏。
你的问题的另一个解决方案是使用非常大量的转换为float
为inf
。 为此,您可以在
使用宏
#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;
根据您的系统/编译器,您可能需要指定标志(例如c99
或c11
将起作用),以便x
显式地转换为float
并且不作为更高的中间精度存储。