(unsigned long)fValue
This converts the float
value to an unsigned long
value, according to the "usual arithmetic conversions".
*(unsigned long *)&fValue
The intention here is to take the address at which fValue
is stored, pretend that there is not a float
but an unsigned long
at this address, and to then read that unsigned long
. The purpose is to examine the bit pattern which is used to store the float
in memory.
As shown, this causes undefined behavior though.
Reason: You may not access an object through a pointer to a type that is not "compatible" to the object's type. "Compatible" types are for example (unsigned
) char
and every other type, or structures that share the same initial members (speaking of C here). See §6.5/7 N1570 for the detailed (C11) list (Note that my use of "compatible" is different - more broad - than in the referenced text.)
Solution: Cast to unsigned char *
, access the individual bytes of the object and assemble an unsigned long
out of them:
unsigned long pattern = 0;
unsigned char * access = (unsigned char *)&fValue;
for (size_t i = 0; i < sizeof(float); ++i) {
pattern |= *access;
pattern <<= CHAR_BIT;
++access;
}
Note that (as @CodesInChaos pointed out) the above treats the floating point value as being stored with its most significant byte first ("big endian"). If your system uses a different byte order for floating point values you'd need to adjust to that (or rearrange the bytes of above unsigned long
, whatever's more practical to you).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…