这是我的函数,它接受浮点的位,并返回下一个浮点和给定浮点之间的距离。在它中,我假设浮点是32位。我的过程是提取尾数和指数,增加尾数,如果指数溢出,增加指数,重建值并减去它们之间的距离。
我有一种感觉,我可能是过于复杂的事情,函数似乎没有使用正确使用的位运算符,即使我以前使用过类似的算法。这里出什么事了?看起来够直截了当了吧?

    unsigned int get_distance(unsigned int bitnumber)
    {
    unsigned int mantissa = 0xff;
    for (int i = 0; i < 24; i++) {
            if (((1 << i) & bitnumber) != 0) mantissa = mantissa | 1 << i;
    }

    mantissa = mantissa++; // increment the mantissa

    unsigned int exponent = 0xff;
    for (int i = 24; i < 31; i++) {
                    if (((1 << i) & floatbits) != 0) exponent = exponent | 1 << i;
    }


    if (mantissa != mantissa) exponent++; // if it overflows, increment the exponent too.

    // create complete bit pattern
    unsigned int final = 0xff;
    for (int i = 0; i < 32; i++) {

            if (i < 24) {
                    if (((1 << i) & mantissa) != 0) final = final | 1 << i;
            }

            if (i >= 24 && i < 31) {
                    if (((1 << i) & exponent) != 0) final = final | 1 << i;
            }

            if (i == 32) {
                    if (((1 << i) & bitnumber) != 0) final = final | 1 << i;
            }
    }

    // get difference b/w original float and new float
    unsigned int result = final - bitnumber;
    return result;
    }

最佳答案

首先,您不必要地使各种字段的提取复杂化(而且,您这样做是不正确的)。一个更简单的方法是:

unsigned int exponent = (bitnumber >> 23) & ((1 << 8) - 1);
unsigned int mantissa = bitnumber & ((1 << 23) - 1);

基本上,向左移动bitnumber直到所需字段的LSB为位0,然后按位并按所需的位移出。表达式((1 << N) - 1)是一个掩码,由最低位的N1s组成。
其次,行mantissa = mantissa++;实际上是未定义的行为,因为post increment和assignment都将尝试为mantissa赋值。相反,你只需要mantissa++
接下来,检查溢出永远不会通过,因为mantissa != mantissa将始终为false。相反,您需要检查是否设置了位23或更高,这可以通过mantissa >= (1 << 23)完成。我还建议将此语句与前面提到的增量分组,这样您就可以
mantissa++;
if (mantissa >= (1 << 23))
    exponent++;

最后,重新构建新的价值观非常简单:
unsigned int final = (exponent << 23) | mantissa;

但是,请注意,如果exponent太大,这将导致不同于您预期的浮动(即负浮动)。还有一些关于无穷大/NaN和非正规数的边界情况,但很可能你不会遇到它们。
要实际使用它,您需要进行一些指针转换,如下所示:
float value = 1.0f; // for example
unsigned int *up = (unsigned int *)&value; // NOTE: this might trigger undefined behavior
unsigned int next = next_value(*up); // next_value is a better name for your function than get_distance
float *fp = (float *)&next; // again, this may be UB
float difference = *fp - value; // this is what you want

09-06 18:39