Reputation: 181
The idea is for this to do pretty much the same thing as this http://www.h-schmidt.net/FloatConverter/IEEE754.html
For example if i plug in 357, i should get 0x43b28000
float unsignedToFloat( unsigned int x ) {
unsigned int result = 0;
return *(float*)&result;
}
but how do I do this?
Convert ieee 754 float to hex with c - printf
I saw this, but there didn't seem to be any good solutions.
Upvotes: 0
Views: 2258
Reputation: 28806
I did it this way:
This one handles 0, INT_MIN and rounding correctly, AFAICT:
#define SIGN_MASK (1 << 31)
#define HIDDEN_MASK (1 << 23)
#define MANTISSA_MASK (HIDDEN_MASK - 1)
#define INT_MIN 0x80000000
#define INT_MAX 0x7FFFFFFF
float intToFloat(int n)
{
int sign;
int exp;
unsigned int half;
if (n == 0)
return 0.0f;
if (n == INT_MIN)
return -(float)(INT_MIN);
sign = n < 0 ? SIGN_MASK : 0;
if (sign)
n = -n;
if (!(n & ~(HIDDEN_MASK | MANTISSA_MASK)))
for (exp = 0; !(n & HIDDEN_MASK); n <<= 1, exp--) ;
else
{
half = 0;
for (exp = 0; n & ~(HIDDEN_MASK | MANTISSA_MASK); exp++)
{
half >>= 1;
if (n & 1)
half |= 0x80000000;
n >>= 1;
}
if (half > INT_MIN || ((half == INT_MIN) && (n & 1) != 0))
{
n++;
if (n == 0x1000000)
{
n = 0; // or 0x800000, doesn't matter.
exp++;
}
}
}
exp = (exp + 127 + 23) << 23;
n = (n & MANTISSA_MASK) | sign | exp;
return *((float *)&n);
}
Upvotes: 1
Reputation: 106197
First, if x
is zero, return zero.
Next find the index of the highest-order non-zero bit in x
. Call it i
.
If i
is less than 24, left-shift x
by 23 - i
to get a normalized significand. Now clear bit 23 to hide the implicit bit, and set bits 23:30 to 127 + i
, which is the biased exponent. Return the result.
Otherwise, right-shift x
by i - 23
to get a normalized significand via truncation, and clear the implicit bit and set the exponent as above. If your desired rounding mode is truncation or round-to-minus-infinity, you are done. Otherwise, you will need to look at the bits that were shifted off the bottom of x
. If the desired rounding mode is round-to-plus-infinity and any of those bits are set, add one to the result and return. Finally, if the desired rounding mode is round-to-nearest-ties-to-even (IEEE-754 default), there are three cases:
b0...
: return the truncated result.b1000...
: this is an exact halfway case. If we call the truncated result t
, you need to return t + (t&1)
; i.e. round up only if t
is odd.b1...1...
: add one to the truncated result and return.Upvotes: 3