C ++双数的混淆二进制编码结果

时间:2014-04-20 02:53:27

标签: c++ encoding double

我知道IEEE双格式给出15-17个有效十进制数字精度。将超过17位有效数字的十进制数转换为double类型将遇到精度损失。例如:

#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("%f\n",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? 

我提到了double类型的编码标准符,发现这代表(-1)^ 0 * 2 ^ 64 * 1 = 2 ^ 64,我想知道为什么这样的编码被打印为18446744073709552000.000000。

1 个答案:

答案 0 :(得分:0)

43 f0 00 00 00 00 00 00对应的确切值为18446744073709551616。我不知道你的printf的具体规则,但是许多库默认会缩短它们的输出,以避免打印大量的任意数字。

例如,与1e100最接近的两倍具有精确值10000000000000000159028911097599180468360808563945281389781327557747838772170381060813469985856815104。这通常不是人们在打印1e100时想要看到的。大多数数字与浮点表示的细节有关,而不是与实际使用有关。

您获得的值18446744073709552000.000000是十进制数字,其中有效数字的最小数字将转换回您的双精度数字,小数点后面的6位数字显示,这是{{1 }} printf所以格式化它是一个非常合理的选择。