2012-11-06 229 views
4

這是怎麼回事?Python cos(90)和cos(270)不是0

測試出sin和cos函數,找出爲什麼當我將座標輸出到SVG文件時,爲什麼我會在錯誤的位置獲得如此精美的定位。所以我製作了這個測試代碼,我可以預測答案是找出原因。奇怪的是,沒有任何影響計算的東西會自我增加這種行爲,而只是我即將停留的位置。如果位置爲0並且在計算後變爲0,則它​​將不起作用,但是如果位置爲1並且在計算後它將變爲1,則它將起作用。

第一個測試:

import math 

cX = 2 
cY = 2 
r = 2 

rcX = cX + (r * math.cos(math.radians(0))) 
rcY = cY + (r * math.sin(math.radians(0))) 

print rcX #4 
print rcY #2 
r = 1 

rlX = rcX + (r * math.cos(math.radians(90))) 
rlY = rcY + (r * math.sin(math.radians(90))) 

print rlX #4 
print rlY #3 
r = 4 

flX = rlX + (r * math.cos(math.radians(180))) 
flY = rlY + (r * math.sin(math.radians(180))) 

print flX #0 
print flY #3 
r = 2 

print r * math.cos(math.radians(270)) 
print flX + (r * math.cos(math.radians(270))) #-3.67394039744e-16 should be 0 
print flY + (r * math.sin(math.radians(270))) #1 

現在我改變CX至3,即使它不會影響計算這是它的工作原理:

r * math.cos(math.radians(270)) 

該計算的結果加到x協調

import math 

cX = 3 
cY = 2 
r = 2 

rcX = cX + (r * math.cos(math.radians(0))) 
rcY = cY + (r * math.sin(math.radians(0))) 

print rcX #5 
print rcY #2 
r = 1 

rlX = rcX + (r * math.cos(math.radians(90))) 
rlY = rcY + (r * math.sin(math.radians(90))) 

print rlX #5 
print rlY #3 
r = 4 

flX = rlX + (r * math.cos(math.radians(180))) 
flY = rlY + (r * math.sin(math.radians(180))) 

print flX #1 
print flY #3 
r = 2 

print r * math.cos(math.radians(270)) 
print flX + (r * math.cos(math.radians(270))) #1 
print flY + (r * math.sin(math.radians(270))) #1 
+6

'-3.67394039744e-16'已經夠接近了嗎? – Mysticial

+0

你得到了什麼輸出? – Wug

+2

您知道轉換爲弧度會遇到舍入錯誤,對嗎? –

回答

5

您正在處理舍入錯誤,這是工作機智(大部分)不可避免的h浮點數學(參見paper已被其他人鏈接以準確理解發生了什麼)。

在許多情況下,您可以減少它們的影響(通過以「智能」順序執行操作或以更「浮點友好」的方式重新構建表達式),但在您的情況下最簡單的做法是簡單地結果例如小數點後6位,並對此感到滿意。當然,你不需要更精確的定位,並且你會得到你期望的「規範」角度的結果。

+0

我不明白這是如何不能在功能開始?沒有閱讀整篇論文,但看起來很有趣。 – Andreas

+2

'cos'不知道它的參數是否受到舍入誤差影響的7/4pi,或者如果您故意傳遞了這個「稍微錯誤」的值,它只是試圖給你所收到參數的餘弦值。您可以在評估後總是舍入返回值,但如果自動舍入,則無法獲得精確度。 –