如何将无符号整数转换为浮点数? [英] How to convert an unsigned int to a float?
问题描述
我需要构建一个函数,该函数返回 (float)x 的位级等价物,而不使用任何浮动数据类型、操作或常量.我想我有它,但是当我运行测试文件时,它返回有一个无限循环.任何调试帮助将不胜感激.
I need to build a function that returns the bit-level equivalent of (float)x without using any floating data types, operations or constants. I think I have it, but when I run the test file, it returns that there's an infinite loop. Any debugging help would be appreciated.
我可以使用任何整数/无符号运算,包括 ||、&&、if、while.另外,我只能使用 30 次操作
I'm allowed to use any integer/unsigned operations including ||, &&, if, while. Also, I can only use 30 operations
unsigned float_i2f(int x) {
printf("
%i", x);
if (!x) {return x;}
int mask1 = (x >> 31);
int mask2 = (1 << 31);
int sign = x & mask2;
int complement = ~x + 1;
//int abs = (~mask1 & x) + (mask1 & complement);
int abs = x;
int i = 0, temp = 0;
while (!(temp & mask2)){
temp = (abs <<i);
i = i + 1;
}
int E = 32 - i;
int exp = 127 + E;
abs = abs & (-1 ^ (1 << E));
int frac;
if ((23 - E)>0)
frac = (abs << (23 - E));
else
frac = (abs >> (E - 23));
int rep = sign + (exp << 23) + frac;
return rep;
}
响应非常有用的评论和答案,这里是更新的代码,现在只有 0x80000000 失败:
In response to the very helpful comments and answers, here is the updated code, now only failing for 0x80000000:
unsigned float_i2f(int x) {
int sign;
int absX;
int E = -1;
int shift;
int exp;
int frac;
// zero is the same in int and float:
if (!x) {return x;}
// sign is bit 31: that bit should just be transferred to the float:
sign = x & 0x80000000;
// if number is < 0, take two's complement:
if (sign != 0) {
absX = ~x + 1;
}
else
absX = x;
shift = absX;
while ((!!shift) && (shift != -1)) {
//std::cout << std::bitset<32>(shift) << "
";
E++;
shift = (shift >> 1);
}
if (E == 30) { E++;}
exp = E + 127+24;
exp = (exp << 23);
frac = (absX << (23 - E)) & 0x007FFFFF;
return sign + exp + frac;
}
有人知道修改后的代码中的错误在哪里吗?再次感谢大家!
Anyone have any idea where the bug is in the revised code? Thank you all again!
推荐答案
您可以做很多事情来改进和清理代码.对于初学者,添加评论!其次,(并减少操作次数),您可以组合某些东西.第三 - 区分可以精确表示的整数"和不能精确表示的整数".
There is quite a lot you can do to improve your code and clean it up. For starters, add comments! Secondly, (and to reduce number of operations), you can combine certain things. Thirdly - differentiate between "integers that can be represented exactly" from "those that cannot".
这里有一些示例代码可以将其中的一些内容付诸实践;我实际上无法编译和测试它,所以可能存在一些错误 - 我试图展示一种方法,而不是为你做任务......
Here is some sample code to put some of these things into practice; I could not actually compile and test this, so it's possible there are some bugs - I am trying to show an approach, not do your assignment for you...
unsigned float_i2f(int x) {
// convert integer to its bit-equivalent floating point representation
// but return it as an unsigned integer
// format:
// 1 sign bit
// 8 exponent bits
// 23 mantissa bits (plus the 'most significant bit' which is always 1
printf("
%i", x);
// zero is the same in int and float:
if (x == 0) {return x;}
// sign is bit 31: that bit should just be transferred to the float:
sign = x & 0x8000;
// if number is < 0, take two's complement:
int absX;
if(sign != 0) {
absX = ~x + 1;
}
else
absX = x;
}
// Take at most 24 bits:
unsigned int bits23 = 0xFF800000;
unsigned int bits24 = 0xFF000000;
unsigned E = 127-24; // could be off by 1
// shift right if there are bits above bit 24:
while(absX & bits24) {
E++; // check that you add and don't subtract...
absX >>= 1;
}
// shift left if there are no bits above bit 23:
// check that it terminates at the right point.
while (!(absX & bits23))
E--; // check direction
absX <<= 1;
}
// now put the numbers we have together in the return value:
// check that they are truncated correctly
return sign | (E << 23) | (absX & ~bits23);
}
这篇关于如何将无符号整数转换为浮点数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!