2017-07-17 1104 views
1

這在其他(也許是所有)語言中無疑是這樣,但我只用Python進行測試。我的問題是這樣的: 在對兩個值進行不同精度的算術運算時,爲什麼NumPy以最高精度返回值的dtype結果?NumPy在浮點運算中將精度降低到更高的精度

例如

import numpy as np 

single = np.array([[1, 2, 3], [4, 5, 6]], np.float32) 
double = np.array([[1, 2, 3], [4, 5, 6]], np.float64) 

diff = single-double 

print "single data type -", single.dtype 
print "double data type -", double.dtype 
print "diff data type -", diff.dtype 

收率:

單個數據類型 - FLOAT32
雙數據類型 - float64
差異數據類型 - float64

據我所知浮動點精度,代表額外的後半部分diff並不準確。在那種情況下,將結果轉換爲最高精度而不是最低精度的原因是什麼?

回答

2

原因是數值計算中的一個原理叫做災難性消除。

考慮兩個浮點數之間稍微小一點的例子。 3.0000900 - 3.000,如果它被丟到4位小數,或者在你的情況下丟到4字節,我們的結果值是0.但是這些值實際上並不相同!我剛纔演示的現象被稱爲災難性的取消。由於這個問題被截斷甚至四捨五入,我們實際上正在丟失信息。

爲了避免這種情況,這些操作的結果始終是類型轉換爲更精確的類型,因爲丟失的信息是最小的。

2

這就是所謂的類型強制,並且至少在NumPy中,它總是會以更高的精度強制類型,因爲這樣你不會意外失去精度,也不會溢出。

例如(關於 「溢出」)與強迫float64它(排序)的作品:

>>> np.float64(1e40) - np.float32(1) 
1e40 

但如果它會強制給float32,你會得到:

>>> np.float64(1e40).astype(np.float32) - np.float32(1) 
inf 

這因爲最大的float323.4028235e+38

>>> np.finfo(np.float32) 
finfo(resolution=1e-06, min=-3.4028235e+38, max=3.4028235e+38, dtype=float32) 
0

答案大多是從mathematics and the types of numbers

類型64的類型包含類型32的整體,與實數類型(浮點數)包含整數類型的方式相同。

無論何時執行計算,如果將結果集映射到更大的數據容器(整數類型64而不是32)內,則可以保證提供令人滿意的結果,但不能保證在映射時不會截斷結果可能較短容器中的一組值,這意味着生成無效結果。

這一直以float和int這種方式。在大多數語言中,float與int相乘會導致float,因爲float(實數)可以在數學上包含int,而相反的則不是true(整數類型不包含實數)。