c - 如何将无符号整数转换为 float ?

标签 c binary type-conversion bit unsigned-integer

我需要构建一个函数来返回 (float)x 的位级等价物,而不使用任何 float 数据类型、操作或常量。我想我有它,但是当我运行测试文件时,它返回有一个无限循环。任何调试帮助将不胜感激。

我可以使用任何整数/无符号运算,包括 ||、&&、if、while。 另外,我只能使用 30 个操作

unsigned float_i2f(int x) {
    printf("\n%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 失败:

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) << "\n";
        E++;
        shift = (shift >> 1);
    }
    if (E == 30) { E++;}
    exp = E + 127+24;
    exp = (exp << 23);
    frac = (absX << (23 - E)) & 0x007FFFFF;
    return sign + exp + frac;
}

任何人都知道修改后的代码中的错误在哪里?再次感谢大家!

最佳答案

您可以做很多事情来改进您的代码并清理它。对于初学者,添加评论!其次,(为了减少操作次数),您可以组合某些东西。第三 - 区分“可以精确表示的整数”和“不能精确表示的整数”。

下面是一些示例代码,可以将其中的一些内容付诸实践;我实际上无法编译和测试它,所以可能存在一些错误 - 我正在尝试展示一种方法,而不是为你做作业......

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("\n%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);

关于c - 如何将无符号整数转换为 float ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19529356/

相关文章:

洋红色内核中具有三个选项的 C 结构

c# - 如何实现二元方程的高斯消元法

c++ - 转换具有多个参数的构造函数

c#-4.0 - TypeConverter 不会转换为 bool 值

c - 用 C 写我自己的 shell

c - 外部数组的地址在编译单元之间不同

c++ - 显示非常大的数字,由 byte[] 表示

javascript - 使用 node.js 从 Google Drive 读取二进制文件

java - 如何使用java将音频文件(mp3文件)转换为二进制文件以及相反?

mysql - 在 MySql 中创建一个 id 为 CHV18000002 的列