这就是我想要做的事情:
//Let Bin2Float be a magic macro that packages specified bit pattern into float as a constant
const float MyInf = Bin2Float(01111111,10000000,00000000,00000000);
我们都知道如何将位模式打包成整数(“二进制常量”黑客),并且这个魔术原型宏的输入与相应的32位整数二进制常量宏的输入相同。将位打包成整数常量不是问题。但是,在玩指针和联合投注之后,我意识到将整数打入浮动类型会导致许多问题(一些在MSVC方面,一些在gcc方面)。以下是要求清单:
答案 0 :(得分:4)
首先,很少需要以这种方式指定浮点常量。对于无穷大,请使用INFINITY
。对于NaN,请使用NAN
或nanf(string)
。这些在<math.h>
中定义。编译器可能将INFINITY
和NAN
编译为某种汇编语言常量(可能在只读数据部分中,可以在指令的直接字段中形成,等等)。但是,除了编译器实现者之外,这不能保证,因为C标准不保证它。 nanf
可能会导致函数调用,尽管如果字符串是常量,编译器可以自由地将其优化为常量。对于有限数,请使用十六进制浮点常数(例如,“0x3.4p5”)。唯一的IEEE 754浮点对象,你不能完全指定这种方式,最后一位,是NaNs。 {C}标准未完全指定nan
和nanf
函数,因此除非实现提供,否则您无法完全控制有效位数。
我不熟悉你提到的二进制常数黑客攻击。假设您有一个提供Bin2Unsigned
的宏unsigned int
,那么您可以使用它:
const float MyInf = (union { unsigned u; float f; }) { Bin2Unsigned(…) } .f;
也就是说,信不信由你,标准的C语法和语义直到比特被重新解释为浮点数。显然,比特的解释取决于实现。但是,复合文字和通过联合重新解释是由C标准规定的。
我使用gcc版本4.2.1(Apple Inc.版本5666)进行测试,目标是x86_64,其中使用-O3和默认选项,结果汇编代码使用常量.long 2139095040
。