2015-06-05 45 views
9

任何人都可以解釋我如何使用printf中的[.precision]與說明符「%g」?我很困惑以下輸出:printf的精度與說明符「%g」

double value = 3122.55; 
printf("%.16g\n", value); //output: 3122.55 
printf("%.17g\n", value); //output: 3122.5500000000002 

我知道%g使用最短的表示法。

但下面還是輸出混淆我

printf("%.16e\n", value); //output: 3.1225500000000002e+03 
printf("%.16f\n", value); //output: 3122.5500000000001819 
printf("%.17e\n", value); //output: 3.12255000000000018e+03 
printf("%.17f\n", value); //output: 3122.55000000000018190 

我的問題是:爲什麼%.16g給出確切的數字,而%.17g不能?

似乎有16位有效數字是準確的。有誰能告訴我原因嗎?

+0

在IEEE浮點數中永遠不會這樣。 – user35443

回答

2

%g使用最短的表示形式。

計算機中的浮點數aren't stored的基數爲10,但是2。這意味着在浮點二進制中表示十進制數時,通常會有一些舍入錯誤。

當您指定%.16g時,表示您希望最短的表示形式的最大值爲16的重要有效數字。

如果最短的表示形式有16以上的數字,則printf會縮短它。縮短將最終削減2,留下3122.550000000000,這實際上是3122.55最短的形式,這就是爲什麼數字。

%g WIL總是給你最短的結果可能的,但如果你說你要17地方的精度和17日舉行包含0一些不同的值,你最終將所有的零和值結束:3122.5500000000002

我的問題是:爲什麼%.16g給出同時%.17g 不能確切的數字?

這實際上是%.17g它給你確切的結果,而%.16g只給你一個圓形近似一個錯誤(相比,在內存中的值)。

如果您想要更精確的定位,請改用%f%F

+0

我知道在呈現浮球時存在路線錯誤。我感到困惑的是,似乎前16位有效數字實際上是我想要的路由錯誤。爲什麼? – cssmlulu

+0

@cssmlulu錯誤發生在17日。 '%.16g'表示你只關心第一個'16'數字,最後一個被忽略。當最後有很多零(不是有效數字)時,'%g'將它們切斷,使其與'3122.55'一樣短。 – user35443

+2

@cssmlulu除@ user35443的評論外,'%g'使用有效數字的數目作爲其精度說明符。這裏更詳細地解釋:[C中的%g和%f有什麼區別?](http://stackoverflow.com/a/5913115/4895040)。有效數字之一規定,[非零數字之間的所有零總是顯着的。](http://www.usca.edu/chemistry/genchem/sigfig.htm),如果使用'.17g ''on'3122.5500000000002',因爲'5'和'2'之間的零被認爲是重要的。這就是爲什麼包含這些零點的原因。 – raymelfrancisco

相關問題