2016-11-14 40 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。它也应尽可能准确。