我是这样做的:
更新
这个可以正确处理 0、INT_MIN 和舍入,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);
}