關於C語言中輸出超精度位數浮點數的問題?

使用的VS2017的同學們這樣做都會輸出這個結果,本人大一新生,望各位大佬解釋下原理,不勝感激


首先將十進位數 0.3 表示為二進位數,用二進位做除法 3 ÷ 10 即可,我們用小學知識列個豎式:

.010011..
------------
1010 ) 1100
1010
----
10000
1010
-----
1100
1010
----
..

可以看到,二進位下,0.3 是一個無限循環小數:0.010011001...(1001 循環)

然後,代碼里的字面量 0.3 是 double 類型的,我們需要把這個無限循環小數裝進 double 里。

假設 VS2017 使用了 IEEE 754 標準的浮點數(實際也確實如此),那麼按照該標準,雙精度浮點數共有 53 位有效數字。我們用初中知識數一下這個無限循環小數的 53 位有效數字:

0.0100110011001100110011001100110011001100110011001100110011001...
|&<------------------------53-----------------------&>|

保留 53 位有效數字,需要把多餘部分做舍入。十進位數,我們一般做四捨五入,而二進位數,奇形怪狀的舍入規則很多。

假設 VS2017 使用了 IEEE 754 里「0 舍 1 入」的舍入規則(看上去實際也是如此),那麼 0.3 的二進位保留 53 位有效數字後就是:

0.010011001100110011001100110011001100110011001100110011

接著,我們將這一二進位小數轉換回十進位,就可以得到:

0.299999999999999988897769753748434595763683319091796875

最後,由於你的格式化字元串是 %.60lf,即小數點後至少顯示 60 個數字,於是最後補了六個 0:

0.299999999999999988897769753748434595763683319091796875000000

(p.s. 請一定注意兩個「假設」的存在。)

以上。


我建議你閱讀《深入理解計算機系統》第二章,以後類似問題你都明白了。


不用深入了解計算機系統,計算機科學概論裡面就說了…


推薦閱讀:

什麼時候中國的手機晶元或系統能成為主流?
學計算機專業,多倫多大學,滑鐵盧大學,麥吉爾大學和英屬哥倫比亞大學裡面,應當選哪個?
計算機專業的學生該怎樣自學量子力學?
你做實驗的時候會用到哪些「神器」,可以視頻展示實驗過程嗎?
學編譯原理有什麼好書?

TAG:編程 | C編程語言 | 計算機科學 | 浮點數 |