【发布时间】:2017-02-02 22:32:52
【问题描述】:
在进行类分配时,我试图仅使用位操作将整数转换为浮点数(仅限于任何整数/无符号操作,包括 ||、&&。还有 if、while)。我的代码适用于大多数值,但有些值没有生成我正在寻找的结果。
例如,如果 x 是 0x807fffff,我得到 0xceff0001,但正确的结果应该是 0xceff0000。我想我的尾数和舍入缺少一些东西,但不能完全确定。我还查看了 SO 上的其他一些线程 converting-int-to-float 和 how-to-manually
unsigned dl22(int x) {
int tmin = 0x1 << 31;
int tmax = ~tmin;
unsigned signBit = 0;
unsigned exponent;
unsigned mantissa;
int bias = 127;
if (x == 0) {
return 0;
}
if (x == tmin) {
return 0xcf << 24;
}
if (x < 0) {
signBit = x & tmin;
x = (~x + 1);
}
exponent = bias + 31;
while ( ( x & tmin) == 0 ) {
exponent--;
x <<= 1;
}
exponent <<= 23;
int mantissaMask = ~(tmin >> 8);
mantissa = (x >> 8) & mantissaMask;
return (signBit | exponent | mantissa);
}
编辑/更新 找到了一个可行的解决方案 - 见下文
【问题讨论】:
-
您对“仅使用按位运算”有一个奇怪的定义。我也在您的代码中看到了关系运算和算术运算。 (以及简单和复合的赋值操作,但我不认为你的意思是排除赋值。)
-
我们可以使用关系比较器以及整数和无符号乘法,但不能进行强制转换(也可以使用 if/while 循环)
-
注意:
0x1 << 31是未定义的行为,尽管它可能对您有用。 -
有趣的@chux,您是否有更多关于其未定义行为或其含义的详细信息?
-
在 C 中,
int溢出是 UB。 1 在 32 位int上左移 31 次就像 2 的 31 次方。超出int范围的值。编译器没有义务生成可靠的代码。可以使用int tmin = INT_MIN;。
标签: c casting bit-manipulation bitwise-operators