一个令人困惑的C++双数二进制编码结果
A Confusing Binary Encoding Result of C++ Double Number
我知道IEEE双格式提供15–17个有效十进制数字的精度。将超过17个有效数字的十进制数转换为双精度类型将导致精度损失。例如:
#include<iostream>
#include<stdlib.h>
void showEncodeOfDouble(unsigned char* db){
const int ByteLength=8;
for(int i=ByteLength-1;i>=0;i--)
printf(" %.2x",db[i]);
printf("n");
}
int main(){
//2^64=18446744073709551616
double d1=18446744073709551616.0; //20bit Significant,Precision Loss
printf("%fn",d1);
showEncodeOfDouble((unsigned char*)&d1);
return 0;
}
输出:
18446744073709552000.000000
43 f0 00 00 00 00 00 00
转换后,原来的20个有效十进制位被削减到只有17。我的问题是:
Why the encoding result is 43 f0 00 00 00 00 00 00?
我参考了双类型的编码标准,发现它代表(-1)^0*2^64*1=2^64,我想知道为什么这样的编码被打印为18446744073709552000.000000。
43 f0 00 00 00 00 00 00
对应的确切值为18446744073709551616
。我不知道printf
的具体规则,但许多库默认情况下会缩短输出,以避免打印大量任意数字。
例如,最接近1e100
的双精度具有精确值10000000000000000159028911097599180468360808563945281389781327557747838772170381060813469985856815104
。这通常不是人们希望在打印1e100时看到的。大多数数字更多地与浮点表示的细节有关,而不是与它的实际使用有关。
您得到的值18446744073709552000.000000
是所有转换回双精度的数字中有效位数最少的十进制数字,在小数点后显示6位数字,这是printf
%f
的默认值,因此它是格式化它的一个非常合理的选择。
相关文章:
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 有根的二进制搜索树.保留与其父级的链接
- 多态二进制函数
- 正在读取二进制文件(is_open)
- visual在c++中将十进制数转换为二进制数
- C++十进制到二进制,如何转换
- cpp二进制搜索问题,计算给定数组中输入元素的出现次数
- 二进制搜索树叶数问题
- 如何将一个ostringstream十六进制字符串字符对转换为单个unit8t等价的二进制值
- 为什么二进制搜索在我的测试中不起作用
- 重载==不适用于二进制树
- 正在尝试重载二进制搜索树分配运算符
- 在C++中将类(带有Vector成员)保存为二进制文件
- 如何从二进制文件中读取字符串
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么
- 带有数组键C++的二进制映射
- 如何将二进制格式的 C++ 对象的 std::vector 保存到磁盘?
- 二进制数之和(使用C样式字符串)
- 如何从dicom文件中读取二进制数据
- 基于编译器选项的编译二进制路径