floating-point - 有人可以解释从十进制到 IEE 754 Binary32 的转换吗?
问题描述
我正在尝试将数字170.3转换为IEE 754 binary32 float:
你可以从下面的图片中看到我的工作:
将 170 转换为二进制
所以二进制中的 170 是 10101010
将 0.3 转换为二进制
我们可以看到模式 1001 将永远重复,所以我们有类似的东西
0.3 = 0.0 1001其中粗体部分重复出现
把这些放在一起
当我们把这些数字放在一起时,我们可以得到整个值的二进制表示:
170.3 = 10101010.0 1001
粗体部分重复出现的地方。
将其转换为标准形式
170.3 = 1.01010100 1001 x 2⁷</p>
这应该如何存储:
这就是我们的 4 个字节(32 位)的分配方式:
- 符号为 0,因为我们使用的是正数
- 指数是 127 + 7 = 134 ,二进制是 10000110
- 然后用循环小数的前 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:
有人可以向我解释我的计算哪里出错了吗?
解决方案
有人可以向我解释我的计算哪里出错了吗?
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 位,最低有效位、符号位和舍入方式,可以确定适当的舍入值。
推荐阅读
- git - Git 克隆在 Linux VM 上通过 HTTPS 故障转移(膨胀:数据流错误)
- apache-spark - 如何在 pyspark 中设置动态 spark.sql.shuffle.partitions?
- python - 像 Photoshop 的椭圆工具一样画圆
- r - 如何检查字符串中元音的存在?并返回 1 或 0?
- amazon-web-services - 使用新记录验证证书
- arrays - 对存储在变量中的 mongo 查询执行 2 个单独的 .map 操作
- javascript - 输入特定消息后踢某人的 Discord 方法。(Javascript)
- spring-boot - Spring Cloud Hoxton.SR5 与最新版本的 Spring Cloud Schema Registry (2.2.1.RELEASE) 不兼容
- node.js - AWS Cognito 放大注册方法不起作用
- c++ - 为什么我的代码在涉及指针时停止运行?