有人可以解释一下从十进制到IEEE 754二进制32位的转换吗?

3
我正在尝试将数字170.3转换为IEE 754二进制32位浮点数
您可以从下面的图片中看到我的工作过程:

将170转换为二进制

所以十进制数170在二进制中表示为10101010。

将0.3转化为二进制

我们可以看到,模式1001将永远重复,所以我们有类似的情况
0.3 = 0.01001,其中粗体部分是循环的。
将这些数字放在一起时,我们可以得到整个值的二进制表示:
170.3 = 10101010.01001,其中粗体部分是循环的。
将其转换为标准形式。

170.3 = 1.010101001001 x 2⁷

存储方式:

以下是我们分配的 4 字节(32 位)的方式:

  1. 符号位为 0,因为我们处理的是正数
  2. 指数位为 127 + 7 = 134,二进制表示为 10000110
  3. 小数部分由循环小数的前 23 位填充,本例中为 01010100100110011001100(其中粗体部分为循环部分)

因此,我们可以将它们组合在一起,得到要存储到我们的 4 字节(32 位)数据中的二进制数据:

01000011001010100100110011001100

当被分成4个字节时,应该是:
01000011-00101010-01001100-11001100

我接着尝试运行这个C++程序,它存储了浮点数并打印出内存内容。
#include <iostream>

/* Prints Contents of Memory Blocks */
static void print_bytes(const void *object, size_t size){
    #ifdef __cplusplus
    const unsigned char * const bytes = static_cast<const unsigned char *>(object);
    #else // __cplusplus
    const unsigned char * const bytes = object;
    #endif // __cplusplus

    size_t i;

    printf("[-");
    for(i = 0; i < size; i++)
    {
        //printf(bytes[i]);
        int binary[8];
        for(int n = 0; n < 8; n++){
            binary[7-n] = (bytes[size -1 - i] >> n) & 1;
        }
        /* print result */
        for(int n = 0; n < 8; n++){
            printf("%d", binary[n]);
        }
        printf("%c", '-');
    }
    printf("]\n\n");
}

int main () {

    std::cout << "\nStoring a Float in Memory";
    std::cout << "\n----------------------------\n\n";

    float height = 170.3f;

    std::cout << "Address is "<< &height << "\n\n";
    std::cout << "Size is "<<  sizeof(height) << " bytes\n\n";
    std::cout << "Value is " <<  height << "\n\n";

    std::cout << "Memory Blocks : \n";
    print_bytes(&height, sizeof(height));

    return 0;
}

但是在输出中,我看到最后一位是1而不是根据我的计算是0。 而且,当使用在线转换器时,最后一位也变成了1。 请问有人可以解释一下我在计算中哪里出错了吗?

如果你只差1,那可能只是一个四舍五入的误差。 - undefined
我不认为这是这种情况。如果我们从一个具有重复模式的数字中取出前23位,它应该总是相同的,对吗? - undefined
你从右边丢掉的第一个位是1,所以如果向上舍入而不是向下舍入,你的最后一位将是1。截断和四舍五入是非常不同的操作,重复模式是无关紧要的。 - undefined
哦,所以被截断的部分会四舍五入成最终的位数? - undefined
是的,没错。我相信IEEE-754有一些非常精确的舍入规则,以确保二进制表示最接近实际值。 - undefined
哦,谢谢,我现在明白了,非常感谢!:) - undefined
1个回答

2

请问有人能够解释一下我在计算中错在哪里了吗?

原帖作者没有正确考虑四舍五入。

通常情况下,转换使用的是舍入后的值(四舍五入到最近的偶数)。

 12345678 9012345678901234
+10000110.                           134
        0.0100110011001100 1 1001...     0.3
+10000110.0100110011001100 1 1001... Sum
                           v vvvvvvv
                           1 |       extra bit past the 24
                             1       "or" of the rest of the bits
+10000110.0100110011001100 1 1       Value prior to rounding
^                        ^ ^ ^       These 4 bits & rounding mode determine round value
+                        1           Round value to add (assume round to nearest, ties to even)
+10000110.0100110011001101           Sum
+ 0000110.0100110011001101           23-bit portion explicitly stored.   

将算法进行修改,添加一个“24th”位(从第0位开始)和所有较小位(25th、26th等)的“或”操作。

通过这两个位、最低有效位、符号位和舍入模式,可以确定正确的舍入值。


这部分发生了什么?被截断的数字是否四舍五入到最后一位,从而变成1? - undefined
@ganeshh123 重新编写以显示步骤。(是的,MS 24之后的位也被考虑在内。) - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接