2016-02-19 110 views
0

爲什麼以下四捨五入不是在Python 3個工作,但只有在Python 2?Python 3中的四捨五入問題

random_nums = np.array([-1, 0, 1, 2, 3]) 
probabilities = np.array([0.01, 0.3, 0.58, 0.1, 0.01]) 
target = dict(zip(random_nums, probabilities)) 
target = {k: round(v, 2) for k, v in target.items()} 

out: 
{-1: 0.01, 
0: 0.29999999999999999, 
1: 0.57999999999999996, 
2: 0.10000000000000001, 
3: 0.01} 
+0

如果您需要確切的花車/雙打舍入,轉換爲字符串輸出時做四捨五入。由於顯示的位數,這與所選浮點精度到達這些數字的距離相近。 –

回答

3

你跟NumPy的工作的Python float對象float64對象,而不是。這有幾個後果:

  1. 在Python 3中,float64對象是使用與NumPy的舍入代碼,而不是Python的四捨五入。對於float,Python的舍入代碼總是給出正確舍入的結果。 NumPy的舍入代碼沒有。 (在Python 2中,這是不可能來覆蓋自定義類型的round操作,所以當你圓一個float64對象在Python 2首先被轉換爲Python float,然後Python的舍入代碼是用來給一個float的結果。這是,你看到上面的原因)

  2. 再次上的Python 3的Python 2和Python 3之間的差別,主要的原因,roundfloat64給出float64結果。在Python 2中,round一個float64對象上給出了一個float結果。

  3. Python float對象有不同的repr,這會給出較愉快的輸出。特別是,Python的浮動repr保證雙向傳遞用於(不太大,不能太小)的十進制值與至多15個顯著數字:的0.58表示是'0.58',例如。 NumPy的float64對象的表示沒有這個屬性:它只是打印出基於存儲的價值的最顯著17個十進制數字的結果。

所以,如果你在一輪之前float對象轉換你的價值觀到Python,你會看到更開心輸出(在某些情況下,結果可能會更一點點準確)。但請注意,僅僅因爲輸出看起來不錯,這並不意味着你得到的結果是確切的。這一切都不改變的事實,0.58精確表示作爲一個Python float(或實際上NumPy的float64,它使用相同的格式)。記住,用二進制浮點數,你看到的不是你得到的。

關於Python 3部分輸出例如:

>>> random_nums = np.array([-1, 0, 1, 2, 3]) 
>>> probabilities = np.array([0.01, 0.3, 0.58, 0.1, 0.01]) 
>>> target = dict(zip(random_nums, probabilities)) 
>>> {k: round(v, 2) for k, v in target.items()} 
{0: 0.29999999999999999, 1: 0.57999999999999996, 2: 0.10000000000000001, 3: 0.01, -1: 0.01} 
>>> {k: round(float(v), 2) for k, v in target.items()} 
{0: 0.3, 1: 0.58, 2: 0.1, 3: 0.01, -1: 0.01} 
0

似乎工作正常。請記住,round返回一個浮點數。

它四捨五入到兩位小數,但浮子固有inprecise(對於幾乎所有的數),因此輸出。

+0

解決此問題的最佳方法是什麼? – Nickpick

+0

......解決什麼問題? –

+0

所以輸出看起來不錯,如果你想的浮點輸出,那麼這就是你能做的最好的只有2位小數 – Nickpick