2016-11-14 51 views
0

考慮一個軸,像這樣:高效渦捲上部​​軸

boundary

現在考慮在位置放置在軸的原子:double pos;0.0 < pos < 1.0。該位置可能會被double dt;替代,該位置可以是任何(+ ve/-ve)加倍,因此double newPos = pos + dt;可能不在0.0 < newPos < 1.0的範圍內。

有沒有什麼辦法來實現環繞例如。如果原子離開右側重新插入左側而沒有導致fmod(這對我的情況可能太慢)?

我有一種感覺,應該有一個直接的方式,因爲當dt是一個整數(在沒有小數部分的意義上),位置保持不變(包括),即。添加0.2 + 1.0仍然是0.2(或2.0,3.0...),我可以使用double frac = myDouble - ((long) myDouble);快速提取小數部分,但是我嘗試的任何內容都不適用於所有情況。

對此的任何想法?

+0

如果以浮點格式存儲值,則必須接受並處理舍入錯誤。 – 2501

+1

聽起來像'double frac = myDouble - ((long)myDouble)'不僅適用於整數,而且適用於所有其他值。例如,你對'0.2 + 1.4'有什麼期望?它是'0.6'嗎? –

+0

@barakmanos'0.2 + 1.0 = 0.2'然後'0.2 + 0.4 = 0.6'所以'0.6' –

回答

1

試試這個:

newPos = pos + dt; 
if (newPos == (long)newPos) 
    newPos = 0; 
else if (newPos > 0) 
    newPos -= (long)newPos; 
else 
    newPos -= (long)newPos-1; 

或者:

newPos = pos + dt; 
newPos -= (long)newPos; 
if (newPos < 0) 
    newPos += 1; 
+0

謝謝,這似乎工作。我會在一個真實場景中嘗試幾次,並讓你知道 –

+0

@ᴘᴀɴᴀʏɪᴏᴛɪs:沒問題。允許我將'> = 0'更改爲'> 0'(儘管它不會有太大區別)。 –

+0

@ᴘᴀɴᴀʏɪᴏᴛɪs:請參閱添加到答案的替代解決方案。 –

1

你不應該轉換成整數和可能的不確定的行爲敷衍了事。而是使用其餘的完全可移植的浮點版本:

const double raw = pos + dt; 
const double wrap = raw >= 1.0 ? fmod(raw , 1.0) : raw; 

既然你提到的結果很少超過1.0,這個功能應該不會造成任何性能問題。即使這樣,執行fmod is fast。它也應儘可能準確。