This is what I am trying to do:
//Let Bin2Float be a magic macro that packages specified bit pattern into float as a constant
const float MyInf = Bin2Float(01111111,10000000,00000000,00000000);
We all know how to package the bit patterns into integers ("binary constant" hacks) and the input to this magic prototype macro is the same as would be for corresponding 32-bit integer binary constant macro. Packaging the bits into integer constant is not a problem. But, after playing with pointer and union punning, I realized that type-punning the integer into float, however, leads to many issues (some on MSVC side, some on gcc side). So here is the list of requirements:
First, there is rarely a need to specify floating-point constants in this way. For infinity, use INFINITY
. For a NaN, use either NAN
or nanf(string)
. These are defined in <math.h>
. The compiler is likely to compile INFINITY
and NAN
to some sort of assembly-language constant (could be in the read-only data section, could be formed in immediate fields of instructions, et cetera). However, this cannot be guaranteed except by the compiler implementors, since the C standard does not guarantee it. nanf
is likely to result in a function call, although the compiler is free to optimize it to a constant, if the string is a constant. For finite numbers, use hexadecimal floating-point constants (eg, “0x3.4p5”). The only IEEE 754 floating-point object you cannot completely specify this way, down the last bit, is NaNs. The nan
and nanf
functions are not fully specified by the C standard, so you do not have full control of the significand bits unless the implementation provides it.
I am unfamiliar with the binary constant hacks you allude to. Supposing you have a macro Bin2Unsigned
that provides an unsigned int
, then you can use this:
const float MyInf = (union { unsigned u; float f; }) { Bin2Unsigned(…) } .f;
That is, believe it or not, standard C syntax and semantics up to the point where the bits are reinterpreted as a float. Obviously, the interpretation of the bits depends on the implementation. However, the compound literal and reinterpreting through a union is specified by the C standard.
I tested with gcc version 4.2.1 (Apple Inc. build 5666), targeting x86_64, with -O3 and default options otherwise, and the resulting assembly code used a constant, .long 2139095040
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.