C/C++中浮點數輸出精度的問題


本文使用C++語言書寫,對於C的小伙伴們,如果編譯不通過的話……就說明C里面沒有這個內容,可以跳過

通常來說,我們書寫程序主要只用整形變量

(signed/unsigned) (long/long long/short) int a;

但是有時候,我們又需要一些小數運算。
所以就會出現

float b;
double c;
long double d;

至於具體使用方法……自行度娘。這里需要注意一下浮點數是有精度的
計算機中的數據是用二進制存儲的。
十進制小數怎么轉換為二進制小數呢?
舉個栗子

\[(0.5)_{10} = (0.1)_2 \\ (0.25)_{10} = {0.01}_2 \]

我們是怎么知道的呢?
推理一下,

\[(0.5)_{10} \times (2)_{10} = (1)_{10} (0.5)_{10} = (1)_{10} \div (2)_{10} = (1)_2 \div (10)_2 = (0.1)_2 \]

然后再根據以下度娘的方法,對於十進制小數,每次乘以2,然后取整數位(0/1),就可以得到二進制下的小數
比如

但是我們也要知道,並不是所有小數乘以2的有限次冪就能得到整數的
比如\((0.8)_{10}\),如果小伙伴們自行轉換一下,就會發現\((0.8)_{10} = (0.110011001100\dots)_2\)
是不是無限循環?
但是計算機也不能無限表示啊
他就只能截斷到某一位,這就會產生精度誤差
比如,\((0.8)_{10}\)在計算機中存儲的是\((0.110011001100)_2\),當然實際上他存儲的位數更多,所以誤差更小
那么\((0.110011001100)_2\)轉換回十進制就是(好難算啊)

\[(0.110011001100)_2 = (1 \times 2^{-1} + 1 \times 2^{-2} + 0 \times 2^{-3} + 0 \times 2^{-4} + \dots)_{10} = (0.79980468750000000000)_{10} \]

這個誤差就是這樣產生的。但是一般輸出的時候由於誤差太小,都會給你四舍五入。
這就是為什么很多題都是叫你保留三位小數,因為float三位之后就會有誤差,對於不同的方法輸出的結果不同。


那么對於浮點數的輸出格式,也很簡單啦
我們可以

printf("%.3f", x);

這里.3其實就是0.3, 表示。。。表示

也可以

cout << fixed << setprecision(3);
cout << x << endl;

這里fixed是強制小數輸出,否則的話……你可能會看到3.42344856131e-31這樣的結果,其實他是精度誤差下的0
setprecision(int)就是設置從此以后cout輸出的數據都帶有int位小數位,不足補0


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM