<menu id="ycqsw"></menu><nav id="ycqsw"><code id="ycqsw"></code></nav>
<dd id="ycqsw"><menu id="ycqsw"></menu></dd>
  • <nav id="ycqsw"></nav>
    <menu id="ycqsw"><strong id="ycqsw"></strong></menu>
    <xmp id="ycqsw"><nav id="ycqsw"></nav>
  • float型保留幾位小數和有效數字(c語言float四舍五入)


    電子計算機只能存儲0和1,人類世界所能認識的任何數據都需要通過轉換為二進制再進行存儲。整數(int)型轉換為二進制存儲很好理解,那么float型數據計算機又是怎么存儲的呢?常說的浮點型數據精度丟失和數據溢出又是怎么回事呢?C++:float型數據存儲原理及精度丟失溢出深入解析

    浮點數示意圖

    位和字節

    位:來自英文bit,音譯為“比特”,表示二進制位。位是計算機內部數據儲存的最小單位,11010100是一個8位二進制數。

    字節:來自英文Byte,音譯為“拜特”,習慣上用大寫的“B”表示。
    字節是計算機中數據處理的基本單位。計算機中以字節為單位存儲和解釋信息,規定一個字節由八個二進制位構成,即1個字節等于8個比特(1Byte=8bit)。八位二進制數最小為00000000,最大為11111111;通常1個字節可以存入一個ASCII碼,2個字節可以存放一個漢字國標碼。

    int型數據存儲

    int型數據根據平臺類型不同,所占用字節大小也不同,這里就按正常的4個字節來講。整型分有符號和無符號,有符號左邊最高位為符號位。

    unsigned int和signed in按四個字節計算,也就是4*8=32位。int默認是signed有符號位的。所以,unsigned int表示的范圍是:0~2的32次方-1。signed int表示的范圍是:-2的31次方~2的31次方-1。

    例如+3,轉為二進制是0000 0011,但是計算機是按補碼存儲整型數據的,正數的補碼就是其本身,但是負數的補碼就不是了。這里不作細講,有興趣的朋友可以翻看我前面的文章,里面有詳細介紹。C++:float型數據存儲原理及精度丟失溢出深入解析

    整形數據存儲方式

    float型數據存儲

    浮點數轉二進制方法

    十進制小數轉換成二進制小數采用”乘2取整,按序取出”法。

    整數部分按整數方式轉,用短除法,小數部分按如下方式,最后再用小數點合起來;

    具體做法是:用2乘十進制小數,可以得到積,將積的整數部分取出,再用2乘余下的小數部分,又得到一個積,再將積的整數部分取出,如此進行,直到積中的小數部分為零,或者達到所要求的精度為止。
    然后把取出的整數部分按順序排列起來,先取的整數作為二進制小數的高位有效位,后取的整數作為低位有效位。

    例:0.734375轉二進制,結果是0.101111。

    0.734375 x 2 = 1.46875

    0.46875 x 2 = 0.9375

    0.9375 x 2 = 1.875

    0.875 x 2 = 1.75

    0.75 x 2 = 1.5

    0.5 x 2 = 1.0

    IEEE二進制浮點數算術標準

    浮點數的存儲方式與整型數據不同。浮點數運算有自己的標準標準,也稱IEEE二進制浮點數算術標準(IEEE 754),是20世紀80年代以來最廣泛使用的浮點數運算標準,為許多CPU與浮點運算器所采用。

    根據國際標準IEEE(電氣和電子工程協會)規定,任何一個浮點數NUM的二進制數可以寫為:
    NUM = (-1) ^ S * M * 2 ^ E;//(S表示符號,E表示階乘,M表示有效數字)

    這個標準是什么意思呢?其實說白了就是二進制的科學計數法:

    十進制:12345678 = 1.2345678*10^7 ;

    二進制:例如十進制11.0,寫成二進制就是1011.0,用IEEE標準表示就是(-1)^0 × 1.011 × 2^3 ,s=0,M=1.011,E=3;

    浮點數存儲

    浮點數在內存中的存儲按下圖所示方式存儲:

    C++:float型數據存儲原理及精度丟失溢出深入解析

    1、對于S,用來表示符號,0為正,1為負

    2、對于M:規定M在存儲時舍去第一個1,只存儲小數點之后的數字。這樣做節省了空間,以float類型為例,就可以保存23位小數信息,加上舍去的1就可以用23位來表示24個有效的信息。

    3、對于E(指數)E是一個字節(8位)整數所以E的取值范圍為(0~ 255),但是在計數中指數是可以為負的,所以規定在存入E時,在它原本的值上加上中間數(127),在使用時減去中間數(127),這樣E的真正取值范圍就成了(-127~128)。

    因此對于32為單精度浮點數:在IEEE-754標準中,32位浮點數X的真值可表示為:

    X = (-1)^S×(1.M)×2 ^(E-127);

    精度丟失

    了解了float型數據的存儲原理,接下來了解一下float精度丟失的原因,以浮點數2.7為例:

    首先,十進制轉換成二進制。由于2.7無法用二進制精確表示,因此此處出現一次精度丟失。

    2.7 => 10.10110011001…

    然后,用IEEE標準表示二進制浮點數,得到s=0,M=1.010110011001…,E=1。

    10.1011001… => (-1)^0 × 1.01011001… × 2^1

    最后,按照IEEE標準保存數據。此時是單精度浮點數,M只能保存小數點后23位,多余的部分被丟棄了,因此此處又一次精度丟失。C++:float型數據存儲原理及精度丟失溢出深入解析

    精度丟失示意

    溢出

    既然存儲有位數限制,那么溢出就很好理解了。超過最大能表示的數就是上溢,超過最小能表示的數就是下溢,只要計算出最大和最小能表示的數十多大就可以得出上下溢出的極限:

    上溢極限:C++:float型數據存儲原理及精度丟失溢出深入解析

    上溢極限

    下溢極限:C++:float型數據存儲原理及精度丟失溢出深入解析

    下溢極限

    版權聲明:本文內容由互聯網用戶自發貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發現本站有涉嫌抄襲侵權/違法違規的內容, 請發送郵件至 舉報,一經查實,本站將立刻刪除。

    發表評論

    登錄后才能評論
    国产精品区一区二区免费