Re: Converting float to long bits
James Kanze wrote:
Apparently, the compiler has inlined the code for the function.
Putting it in a separate translation unit should solve this
problem, most of the time.
As long as the function implementation does not share a similar problem.
In fact it does not.
[...]
given toI32Bits, defined as above, the only reason it might not
work is because the compiler authors are being perverse, and are
trying intentionally to trip you up, even at the expense of
ignoring the intent of the standard.
:-)
A bug report would not be that bad.
[...]
The C functions frexp and ldexp provide a defined way to
operate with floating point values.
If you want to be really, really portable, such functions are
the only way. But suppose you need to output floats in IEEE
binary format (e.g. for XDR), and your portability requirements
only include Windows and the major Unix platforms. All of which
use IEEE internally. Some ugly type punning, like the above,
can be significantly faster (and results in a lot shorter code).
Anyway, one safe way of doing it is by using memcpy; the
compiler isn't allowed to mungle that one, since the integer and
the float are in fact two different variables, and the copy uses
void*, which the compiler must consider as a possible alias,
regardless of the other type.
A union should do the job as well. And it results more or less the same
UB as before.
long toI32Bits(float value)
{ union
{ float f;
long l;
} data;
data.f = value;
return data.l;
}
does the job. Even when the function is inlined. Of course, the code is
a bit less efficient.
Marcel