这个想法是为了做同样的事情 http://www.h-schmidt.net/FloatConverter/IEEE754.html
例如,如果我插入357,我应该得到0x43b28000
float unsignedToFloat( unsigned int x ) {
unsigned int result = 0;
return *(float*)&result;
}
但我该怎么做?
Convert ieee 754 float to hex with c - printf
我看到了这一点,但似乎没有任何好的解决方案。
答案 0 :(得分:3)
首先,如果x
为零,则返回零。
接下来找到x
中最高阶非零位的索引。称之为i
。
如果i
小于24,则x
左移23 - i
以获得规范化的有效数字。现在清除第23位以隐藏隐含位,并将位23:30设置为127 + i
,这是有偏差的指数。返回结果。
否则,通过x
右移i - 23
以通过截断获得标准化有效数,并清除隐含位并如上所述设置指数。如果你想要的舍入模式是截断或圆到无穷大,你就完成了。否则,您需要查看从x
底部移出的位。如果所需的舍入模式为round-to-plus-infinity,并且设置了这些位中的任何一位,则在结果中添加一个并返回。最后,如果所需的舍入模式为round-to-nearest-ties-even-even(IEEE-754 default),则有三种情况:
b0...
:返回截断的结果。b1000...
:这是一个完全中途的情况。如果我们调用截断结果t
,则需要返回t + (t&1)
;即仅在t
为奇数的情况下才进行整理。b1...1...
:在截断的结果中添加一个并返回。答案 1 :(得分:1)
我是这样做的:
这个处理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);
}