0

Consider an axis like so:

boundary

Now consider an atom placed on the axis at position: double pos; with 0.0 < pos < 1.0. The position may be displaced by double dt; which can be any (+ve/-ve) double thus double newPos = pos + dt; could possibly not lie within the range 0.0 < newPos < 1.0.

Is there any way to implement a wrap around eg. if atom leaves on the right side re-insert on the left without resulting to fmod (which may be too slow for my case)?

I have a feeling there should be a straight-forward way since when dt is an integer (in the sense that there is no fractional part) the position remains unchanged (with wraparound) ie. adding 0.2 + 1.0 is still 0.2 (or 2.0,3.0...) and I can extract the fractional part quickly enough using double frac = myDouble - ((long) myDouble); but anything I try doesn't really work on all cases.

Any ideas on this?

ᴘᴀɴᴀʏɪᴏᴛɪs
  • 7,169
  • 9
  • 50
  • 81

2 Answers2

1

Try this:

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

Or alternatively:

newPos = pos + dt;
newPos -= (long)newPos;
if (newPos < 0)
    newPos += 1;
barak manos
  • 29,648
  • 10
  • 62
  • 114
1

You shouldn't muddle with conversions to integers and possible undefined behavior. Rather use the completely portable floating point version of remainder:

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

Since you mentioned that the results rarely exceeds 1.0, this function shouldn't cause any performance problems. Even if it does, the implementation of fmod is fast. It should also be as accurate as possible.

Community
  • 1
  • 1
2501
  • 25,460
  • 4
  • 47
  • 87