2010-05-04 186 views
0

我有在Python兩個浮體,我想減,即在Python中最多保留兩位小數的算術運算?

v1 = float(value1) 
v2 = float(value2) 
diff = v1 - v2 

我想要的「差異」被計算了到小數點後兩位,即使用的V1 %.2f和v2的%.2f計算它。我怎樣才能做到這一點?我知道如何打印v1和v2達到兩位小數,但不知道如何做這樣的算術。

我試圖避免的特定問題是這樣的。假設:

v1 = 0.982769777778 
v2 = 0.985980444444 
diff = v1 - v2 

,然後我打印到文件中:

myfile.write("%.2f\t%.2f\t%.2f\n" %(v1, v2, diff)) 

然後我會得到輸出:0.98 0.99 0.00,這表明有V1和V2之間沒有區別,即使打印結果表明有0.01的差異。我怎樣才能解決這個問題?

謝謝。

+0

我能做到這一點,只需做: 輪(V1,2)和圓形(V2,2)?如果可能的話,我想避免使用十進制等額外的庫。 – user248237dfsf 2010-05-04 00:07:24

+0

爲什麼你只想用2位有效數字進行計算?以最高精度進行計算並在最後格式化結果時出現什麼問題?你是否會混淆有意義的數字和小數位? – 2010-05-04 00:08:42

+0

這是問題。如果我計算沒有四捨五入的差異,那麼我使用「%.2f」將結果打印到一個文件中,這意味着我可以將v1 = 0.982769777778打印爲「0.98」並將v2 = 0.985980444444打印爲「0.99」,而差異打印爲「0.00」,這是誤導。這是我想要解決的問題。有任何想法嗎? – user248237dfsf 2010-05-04 00:11:21

回答

3

你在評論中說,你不想使用decimal,但它聽起來像你真的應該在這裏使用。請注意,它不是一個「額外的庫」,因爲它自v2.4起默認提供給Python,您只需要import decimal。當您想要顯示值時,可以使用Decimal.quantize將數字四捨五入爲小數點後兩位顯示,然後取小數點後的差值。

>>> v1 = 0.982769777778 
>>> v2 = 0.985980444444 
>>> from decimal import Decimal 
>>> d1 = Decimal(str(v1)).quantize(Decimal('0.01')) 
>>> d2 = Decimal(str(v2)).quantize(Decimal('0.01')) 
>>> diff = d2 - d1 
>>> print d1, d2, diff 
0.98 0.99 0.01 
+0

您能解釋一下如何使用十進制來獲得連貫的打印,同時仍然有精確的算術?整體解決方案有什麼問題? – user248237dfsf 2010-05-04 00:13:49

+0

@ user248237:添加的代碼。 – 2010-05-04 00:18:38

+0

這比原來的,更簡單,更高效的代碼更精確。 – 2010-05-04 01:43:49

0

有關float類型的事情是,你不能真正控制計算與做了什麼精度。 float類型讓硬件執行計算,並且通常以最有效的方式進行。因爲浮點數(和大多數機器優化的東西一樣)是二進制的,而不是十進制的,所以並不直接(或有效)強制這些計算的精確度爲,其十進制數爲。有關相當詳盡的解釋,請參見the last chapter of the Python tutorial。用浮點數可以做的最好是計算的結果(最好只是格式化時)。

爲了控制實際計算和精度(十進制表示法,不少於),您應該考慮使用decimal模塊中的小數代替。它可以讓你對幾乎所有的東西都有更多的控制,儘管它的速度很快。

1

我以前用過窮人的固定點。實質上,使用整數,將所有數字乘以100,然後在打印之前將它們除以100。

最近在Slashdot上有類似的問題。

0

你是什麼意思「兩位有意義的人物」? Python float有大約15個sigfigs,但它確實有表示錯誤和舍入錯誤(decimal.Decimal。)http://docs.python.org/tutorial/floatingpoint.html可能會證明您是一個有趣的閱讀,以及關於浮點數的大量資源。

float通常具有表示真實數字的精確度,例如物理測量值:權重,距離,持續時間,溫度等。如果要打印出某種顯示浮動的方式,請使用字符串格式爲你建議。

如果您想精確表示固定精度的事物,您可能需要使用整數。你必須自己記住小數點位置,但這通常不會太困難。

decimal.Decimal被推薦的方式太多了。它可以調整爲特定的,高於浮點的精度,但這很少需要;我不認爲我曾經看到過這個問題,因爲有人應該使用decimal.Decimaldecimal.Decimal可以準確地表示十進制數,並控制四捨五入的工作方式,這使得它適合在某些情況下表示金錢。

+0

我理解計算精度與顯示精度之間的差異,即您輸出到文件的精度。我上面的例子表明,這可能會導致誤導輸出。我的問題是:我怎麼能解決這個問題?十進制解決方案是什麼? – user248237dfsf 2010-05-04 00:18:19

+0

@ user248237,如果百分之一是你的重要位,比你不應該在意你的答案是百分之一。這不是浮游物所特有的,這更一般地說是我們處理代表我們正在處理的數字的東西。 「0.01」在這裏比「0.00」更不真實(會有更大的誤差),因此顯示它不會是真正的事情。 – 2010-05-04 00:27:05

+0

當我說我們只是在處理數字顯示不準確時發生這種情況時,我並不意味着我們在馬虎或懶惰時這樣做;例如,在Excel或OOCalc中輸入您的測試編號,並將小數點後的位置顯示爲兩位數字 - 這種小小的打嗝將會發生。 – 2010-05-04 05:05:40

0

您可以使用不同的格式字符串來格式化它。試試'%.2g''%.2e'。任何體面的C/C++ reference將描述不同的說明符。 %.2e使用指數表示法將值格式化爲三位有效數字 - 2表示小數點後面的兩位數字及其之前的一位數字。 %.2g將導致%.2f%.2e,這取決於哪一個將在最小的空間量中產生兩個有效數字。

>>> v1 = 0.982769777778 
>>> v2 = 0.985980444444 
>>> print '%.2f' %v1 
0.98 
>>> print '%.2g' %v1 
0.98 
>>> print '%.2e' %v1 
9.83e-01 
>>> print '%.2g' %(v2-v1) 
0.0032 
>>> print '%.2e' %(v2-v1) 
3.21e-03 
+0

@ D.Shawley:我認爲OP希望得到2位小數的結果,而不是兩位有效數字。我已將問題更新爲我認爲的意思。 – 2010-05-04 00:55:59