最近遇到一个问题,double数据在不同数据库中存储时,如果位数超过16位,不同数据库会显示不同结果。Double在MySQL ClickHouse TDengine 中的显示精度
那么这个数据是如何处理,如何存储的呢? 通过查询资料有了一个初步的认知。

下图为IEEE double类型存储结构,后面的52【0~51】个字节是存储尾数,前面11【52-62】个字节存储指数,第一个用于标记正负。
引用一篇文章 大白话说float型的精度和范围C/C++ 中double类型数据处理_bash
C/C++ 中double类型数据处理_c++_02

那么数据到底是如何处理的呢?
我们做一个实验。
随便选一个超过16位的数字:6748392716482657358
将其转换为二进制

[root@test1 C]# echo "obase=2;6748392716482657358"|bc
101110110100111000110110110101111001110110010000011110001001110

查看一下数据位数

[root@test1 C]# echo "obase=2;6748392716482657358"|bc|wc
      1       1      64

总共有63位【wc 会计算尾部$符号,所以会多一位】。

之前写错了,汗 先把结果留下,,后续补充

补充:

先声明,不一定正确。
前面提到double只能存储52位。
但是 在《数值计算指南》中有如下描述:
C/C++ 中double类型数据处理_bash_03
《80x86 IBM PC及兼容计算机》中对实数如何转换为浮点数(float),描述如下:

1.将实数转化为二进制形式
2.采用科学计数法标识二进制数:1.xxxxx E yyyyy
3.正数的第31位设为0,负数为1
4.将实数部分 yyyyy 加上7F得到偏移指数,并置于23~30位
5.有效数字 xxxxx 置于第22~0位

按照上述步骤:
1.6748392716482657358 转换为二进制
101110110100111000110110110101111001110110010000011110001001110
2.科学计数法标识
1.01110110100111000110110110101111001110110010000011110001001110 E 62
3. 63位设为0
4. 不管了,不重要
5. 01110110100111000110110110101111001110110010000011110001001110 取52位放到0~51位上

因此:
对于以上数值6748392716482657358
我们取53位

[root@test1 C]# echo "obase=2;6748392716482657358"|bc|cut -c 1-53
10111011010011100011011011010111100111011001000001111
[root@test1 C]# echo $((num=2#101110110100111000110110110101111001110110010000011110000000000))
6748392716482657280

我们验证一下:

#include <stdio.h>
main()
{
    double  num;
    num=6748392716482657358;
    printf ("%f \n", num);
}

C/C++ 中double类型数据处理_数据_04

写在最后:

以上描述不知是否正确,还请大佬们指正。