3

I need to reset the value of a variable called theta back to 0 everytime its value reaches or exceeds 2 PI. I was thinking something along the lines of:

int n = 10;
float inc = 2*PI/n;
for(int i=0;i<10;i++)
    theta = (theta + inc) % 2*PI;

Of course it wont work because % doesn't work on floating points in C. Is there another equivalent or better way to achieve what I'm trying to do here? All replies are welcome. Thanks

First User
  • 704
  • 5
  • 12

2 Answers2

2

Since division is really just repeated subtraction, you can get the remainder by checking if the value is at least 2*PI, and if so subtract that value.

int n = 10;
float inc = 2*PI/n;
for(int i=0;i<10;i++) {
    theta += inc;
    if (theta >= 2*PI)  theta -= 2*PI;
}

Note that because the amount of the increment is less than the 2*PI limit we can do the "over" check just once. This is likely cheaper than the operations that would be involved if fmod was called. If it was more you would at least need while instead, or just use fmod.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • Thanks! I'll keep this approach in mind. – First User Jun 26 '20 at 15:31
  • 1
    Just a note for future readers that if `inc` were potentially greater than `2*PI`, this code would need to be modified because you might need to subtract `2*PI` more than once per iteration. – Nate Eldredge Jun 26 '20 at 15:35
  • And if you increment by 6*PI just once? this naive "mod" approach needs a bit of work to ensure that it's going to be less than the value you want. – Shark Jun 26 '20 at 15:35
  • 1
    @Shark It was done this way specifically because `inc` is less than `2*PI`, otherwise I would have suggested something else. – dbush Jun 26 '20 at 15:42
  • yeah, generally this will work just in the OP's case, but as @NateEldredge also mentioned - if it goes over the modulus by more than once, it breaks. And since question is titled the way it is, future readers will stumble on it as well, and they probably will not be working with it in a [0, 2*PI] range :) – Shark Jun 26 '20 at 16:23
2

Use the standard fmod function. See https://en.cppreference.com/w/c/numeric/math/fmod or 7.2.10 in the C17 standard.

The fmod functions return the value x − n y , for some integer n such that, if y is nonzero, the result has the same sign as x and magnitude less than the magnitude of y.

So theta = fmod(theta, 2*PI) should be what you want, if I understand your question correctly.

If it really must be done on float instead of double, you can use fmodf instead.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82