2014-03-06 57 views
0

標題不言自明。這裏發生了什麼?我怎麼能得到這個不發生?我真的不得不改變我的所有單位(這是一個物理問題),以便我可以得到一個足夠大的答案,python不會將1-x取整爲1?一個減一個小數字等於一個?處理小數字

代碼:

import numpy as np 
import math 

vel=np.array([5e-30,5e-30,5e-30]) 

c=9.7156e-12 

def mag(V): 
    return math.sqrt(V[0]**2+V[1]**2+V[2]**2) 

gam=(1-(mag(vel)/c)**2)**(-1/2) 

print(mag(vel)) 
print(mag(vel)**2) 
print(mag(vel)**2/(c**2)) 
print(1-mag(vel)**2/(c**2)) 
print(gam) 

輸出:

>>> (executing lines 1 to 17 of "<tmp 1>") 
8.660254037844386e-30 
7.499999999999998e-59 
7.945514251743055e-37 
1.0 
1.0 
>>> 
+6

誰需要閱讀「什麼每臺計算機科學家需要知道的關於浮點型」另一個人。或者,也許誰想要使用非浮點類型和儘可能多的sigfig。 –

+0

好的 - 我知道它已經與此有關,但我不知道替代方案。我很少有無花果無花果,但我不知道如何做到這一點? – doublefelix

+0

查看'decimal'模塊,它允許您設置所需的精度。 –

回答

1

在蟒蛇decimal可以工作,也許mpmath

如在此SO article

如果你願意使用Java(而不是Python)的討論,你可能能夠使用BigDecimal的,或apfloatJScience

8.66e-30只使用3個sig,但要說明1減去需要超過30個。如果超過16個有效數字,則需要使用其他字符來表示數字,例如非常長的字符串。但是用長字符串做數學很困難。您也可以在非常長的字節值數組上執行二進制計算。可以使字節值表示由您選擇的比例因子修改的非常大的整數值。因此,如果您可以支持並且大於1E60的整數,那麼您可以交替調整該值,以便可以用1的最大值表示1E-60。您可以使用大約200位或25字節以及400位,您應該能夠精確地表示1E60到1E-60的整個範圍。可能已經有公用事業公司可以在那裏執行這種類型的數學計算,因爲他們可能想要將PI表示爲1000個位置,而這對於雙數來說是無法做到的。

另一個有用的技巧是使用比例因子。也就是說,在原始座標空間中,您不能進行減法,因爲數字不能表示值。但是,如果您假設如果進行小的調整,您不會同時關心大的調整,那麼您可以對數據執行轉換。例如,你從你的數字中減去1。那麼你可以將1-1E-60表示爲-1E-60。你可以在變換空間中非常精確地完成很多操作,但是非常清楚,如果你試圖將它們從變換空間轉換回來,它們將會失去作用,無關緊要。放大地圖時,這種策略非常有用。對於單精度浮點DirectX計算,以緯度和經度爲單位對千分尺進行調整將不起作用。但是,當你放大時,你可以暫時改變你的比例尺,以便這些操作能夠正常工作。

如此複雜的數字可以用一個大數字加上代表小比例調整的第二個數字來表示。因此,例如,如果您的雙數中有16位數字,則可以使用第一個數字來表示該數值的大部分,例如從1到1E16,而第二個數字代表額外的小部分。除了使用16位數字可能會因爲雙精度代表大數值的能力而產生錯誤,所以您可能只使用15或14個左右來保證安全。

1234567890.1234567890 

成爲

1.234567890E9 + 1.23456789E-1. 

,基本上更大的精度更方面的複數得到。但是,當每個術語或多或少具有數學獨立性時,當這種事情發揮的很好時,如果您必須進行大量嚴格的計算,並在這些尺度上進行操作,那麼在這些值之間進行記錄可能會更多痛苦比它值得。

0

我想你不會得到你期待的結果,因爲你正在處理計算機數學極限。關於這種計算的一點是,沒有人可以避免這個錯誤,除非你找/找到一些有無限(理論上)小數的模型,並且你可以用它們來操作。如果對於您正在嘗試解決的問題而言,這太過分了,也許您只需要小心並嘗試去做任何您需要的事情,只是嘗試在計算中處理這些錯誤。

有很多書目在那裏用許多不同的方法來處理計算中的錯誤,有助於避免但避免這些錯誤。

希望我的回答可以幫助,不辜負你..

相關問題