最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++中double浮點數精度丟失的深入分析

 更新時間:2021年01月05日 16:07:12   作者:adanus  
這篇文章主要給大家介紹了關于C++中double浮點數精度丟失的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

看了一篇關于C/C++浮點數的博文,在Win32下,把int, 指針地址,long等4字節(jié)整數賦給一個double后,再用該double數賦給原始類型的數,得到的結果于最初的數值一致,即不存在任何精度丟失。例如下面的結果將總是true:

 long a=123456; //assign any long number here
 double db=a;
 long b=db;
 printf("%s\n",a==b?"true":"false");

但是對于long long或win64下的指針地址等8字節(jié)整數將存在精度丟失,于是對這方面做了一個簡單的測試:

#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(){
 
 unsigned long long maxULL=0xffffffffffffffff; //2^64-1=18446744073709551615,
             //max unsigned long long
 printf("%llu\n",maxULL);

 double d1=maxULL;        //20bit Significant,Precision Loss 
 printf("%f\n",d1);      

 maxULL=d1;
 printf("%llu\n",maxULL);
 
 showEncodeOfDouble((unsigned char*)&d1);

 system("pause");
 return 0;
}

輸出的結果如下(visual studio,win32):

18446744073709551615
18446744073709552000.000000
9223372036854775808
 43 f0 00 00 00 00 00 00

至此,有兩點疑問(暫時不理會代碼中showEncodeOfDouble的結果):

  1)為什么丟失精度后得到的double數是18446744073709552000.000000?
  2)為什么將double數重新轉化為unsigned long long后得到的數又和double不一致呢?

對于這兩個問題,需要對C++浮點數的規(guī)格有一定的了解。

1  IEEE浮點標準

C/C++采用的是IEEE浮點標準,它以“二進制的科學表示法”表示一個小數:

其中M是一個整數部分僅有一位的二進制小數,例如1.011,表示十進制下的1.375。E表示該小數以2為底時的階數?;谝陨系谋硎痉绞?,小數需要對三部分進行編碼:表示符號的s,及階碼E、尾數碼M。C++中的double類型三種編碼所占的位數如圖所示。

53位尾數碼所能達到的精度為53二進制位,約為16 個十進制位( 53 log10(2) ≈ 15.955) [1],尾數碼的編碼中還有一個隱含的開頭整數位1(或0,當11位階碼全0時)因此實際中可得15-17位十進制的精度。當有效位數最多15位的十進制數轉換成double然后重新轉換為原來的十進制類型時,數值保持一致;另一方面,將一個double數轉化為可以容納17位以上有效數字的十進制數再重新轉化為double,結果數值也保持一致。

這就解釋了為什么4字節(jié)的整數轉化為double重新轉化能保持一致(2^32=4294967296僅10個有效位),而8字節(jié)的整數卻可能丟失精度(2^64-1=18446744073709551615共20個有效位)。但第一個問題中整數丟失精度后轉化成的double數值是怎么來的呢,這需要了解C++階碼和尾數對于double數值的意義。

2 階碼編碼和尾數編碼

在階碼編碼中,有一個常數偏置量Bias=1023,假設11位階碼所代表的無符號整數值為e,

1)若e不為0(11位全為1時用于表示特殊數字,此處不討論),則double數值為

2)若e=0,則小數值為

 

那么,可以看函數showEncodeOfDouble了,它的作用是將一個double數的編碼按字節(jié)打印出來(左邊是高字節(jié)),按其打印結果按照上面計算,可知double編碼值表示的數值是2^64,這是合理的,當把精度較高的整數轉化為double時,C++采用向偶數舍入的方式得到最接近的值[2]。至于打印出的結果,屬于C++浮點數打印中的細節(jié)問題。

3 C++浮點數打印

許多C/C++的庫中在輸出double時,通常有意使得輸出結果簡短些(即使設置了足夠多的可見位數),以避免較大位數的輸出。直接使用C中的printf或cout打印double數時,打印顯示的結果也有可能是帶有精度丟失的結果,可使用16進制的方式打印出更精確的double:

printf("%a\n",d1);

得到的輸出結果為:

0x1.000000p+64

至此問題1實際上只是C++中,將高精度整數轉double時的偶數舍入問題。

對于問題2,從float或double轉換成int,值將會被向零舍入.例如1.999將被轉換成1而-1.999將會被轉換成-1。進一步來說,值有可能會溢出。C語言標準沒有對這種情況指出固定的結果,這種轉換行為是無定義的。

參考鏈接:

[1] http://en.wikipedia.org/wiki/Double-precision_floating-point_format#cite_note-whyieee-1

[2]深入理解計算機系統(tǒng),Randal E. Bryant, 機械工業(yè)出版社

[3]http://stackoverflow.com/questions/4738768/printing-double-without-losing-precision

到此這篇關于C++中double浮點數精度丟失的深入分析的文章就介紹到這了,更多相關C++ double浮點數精度丟失內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C++的字符串分割函數的使用詳解

    C++的字符串分割函數的使用詳解

    本篇文章主要介紹了C++的字符串分割函數,主要用strtok、STL、Boost進行字符串分割,有需要的可以了解一下。
    2016-11-11
  • 詳解C++11中的右值引用與移動語義

    詳解C++11中的右值引用與移動語義

    本篇文章主要介紹了詳解C++11中的右值引用與移動語義,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02
  • QT應用啟動失敗排查方法小結

    QT應用啟動失敗排查方法小結

    啟動QT應用經常會碰到應用啟動失敗,qt platform plugin無法啟動,本文就來介紹一下QT應用啟動失敗排查方法小結,具有一定的參考價值,感興趣的可以了解以下
    2023-09-09
  • C++大數模板(推薦)

    C++大數模板(推薦)

    本篇文章是對C++大數模板的程序代碼進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • C語言實現(xiàn)簡易通訊錄完整流程

    C語言實現(xiàn)簡易通訊錄完整流程

    這篇文章主要為大家介紹了C語言實現(xiàn)簡易通訊錄的完整流程,每個環(huán)節(jié)都有完整代碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2022-02-02
  • C語言實現(xiàn)魔方比賽管理系統(tǒng)

    C語言實現(xiàn)魔方比賽管理系統(tǒng)

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)魔方比賽管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • C語言實現(xiàn)的猴子吃桃問題算法解決方案

    C語言實現(xiàn)的猴子吃桃問題算法解決方案

    這篇文章主要介紹了C語言實現(xiàn)的猴子吃桃問題解決方案,較為詳細的分析了猴子吃桃問題并給出了C語言算法的實現(xiàn)方法,具有一定參考借鑒價值,需要的朋友可以參考下
    2016-10-10
  • Qt中QList與QLinkedList類的常用方法總結

    Qt中QList與QLinkedList類的常用方法總結

    這篇文章主要為大家詳細介紹了Qt中QList與QLinkedList類的常用方法,文中的示例代碼講解詳細,對我們學習Qt有一定的幫助,需要的可以參考一下
    2022-12-12
  • C語言 將字符串逆序輸出的實例

    C語言 將字符串逆序輸出的實例

    這篇文章主要介紹了C語言將字符串逆序輸出的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • C++之默認參數詳解

    C++之默認參數詳解

    這篇文章主要介紹了C++的默認參數,是C++入門學習中的基礎知識,需要的朋友可以參考下,希望能夠給你帶來幫助
    2021-11-11

最新評論

环江| 渑池县| 敦化市| 黄平县| 建平县| 田东县| 本溪| 新源县| 房产| 威信县| 竹北市| 洛川县| 东港市| 克什克腾旗| 镇安县| 冕宁县| 蒲江县| 张家港市| 庆元县| 崇仁县| 英超| 略阳县| 渑池县| 滨海县| 页游| 资中县| 扎赉特旗| 独山县| 兴化市| 井研县| 饶河县| 富源县| 锡林郭勒盟| 都匀市| 灯塔市| 徐闻县| 沂源县| 海原县| 崇左市| 新闻| 鄂伦春自治旗|