關於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. 請一定注意兩個「假設」的存在。)
以上。
我建議你閱讀《深入理解計算機系統》第二章,以後類似問題你都明白了。
不用深入了解計算機系統,計算機科學概論裡面就說了…
推薦閱讀:
※什麼時候中國的手機晶元或系統能成為主流?
※學計算機專業,多倫多大學,滑鐵盧大學,麥吉爾大學和英屬哥倫比亞大學裡面,應當選哪個?
※計算機專業的學生該怎樣自學量子力學?
※你做實驗的時候會用到哪些「神器」,可以視頻展示實驗過程嗎?
※學編譯原理有什麼好書?