首页 > 解决方案 > 有人可以解释从十进制到 IEE 754 Binary32 的转换吗?

问题描述

我正在尝试将数字170.3转换为IEE 754 binary32 float

你可以从下面的图片中看到我的工作:

将 170 转换为二进制

170 进入二进制工作

所以二进制中的 170 是 10101010

将 0.3 转换为二进制

0.3 进入二进制工作

我们可以看到模式 1001 将永远重复,所以我们有类似的东西

0.3 = 0.0 1001其中粗体部分重复出现

把这些放在一起

当我们把这些数字放在一起时,我们可以得到整个值的二进制表示:

170.3 = 10101010.0 1001

粗体部分重复出现的地方。

将其转换为标准形式

转换为 Base 2 标准格式工作

170.3 = 1.01010100 1001 x 2⁷</p>

这应该如何存储:

这就是我们的 4 个字节(32 位)的分配方式:

  1. 符号为 0,因为我们使用的是正数
  2. 指数是 127 + 7 = 134 ,二进制是 10000110
  3. 然后用循环小数的前 23 位填充分数,在本例中为 01010100 100110011001100(其中循环部分以粗体显示)

所以我们可以将它们组合在一起,将二进制数据存储到我们的 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:

在线转换器

有人可以向我解释我的计算哪里出错了吗?

标签: floating-pointieee-754

解决方案


有人可以向我解释我的计算哪里出错了吗?

OP 没有正确考虑四舍五入。

通常转换使用四舍五入的值(四舍五入到最接近的,连到偶数)

 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.   

将算法修改为 1)多一位,“第 24”位(从第 0 位开始)和 2)所有较小位(第 25、第 26 等)的“或”。

从这 2 位,最低有效位、符号位和舍入方式,可以确定适当的舍入值。


推荐阅读