angle = (angle + 1) % 32;
angle = (angle + 31) % 32;
To generalize this trick a bit, (a + b) % c can be written as
(a + b + c) % c, to get positive results from a negative “b”, as long
as abs(b) < c (that is, as long as the +c is enough to push it back
= 0). If that’s not the case, there’s “t = (a + b) % c” (gives a
number between -c and c, exclusive) and then “(t + c) % c”.
This is the faworable way to use clamped values I think, because it is
general and takes only about twice the time that the AND version uses.
This is good if the divisor is not an exact power of two. How ever
if it is the original example, which uses and is faster, so no
reason to use this.
(Oh. I had to read this for a moment to figure out what you meant.
Tip: it helps to capitalize boolean operations–“which uses AND”–for
readability.)
Yep my mistake didn’t hit the caps lock while writing. No I made sure I
did.
This is incorrect. The compiler will use a bitwise AND for integer
MOD when possible; using AND has no effect except to make the code
harder to understand.
No it is not. Try it out. I did.
If you do, make sure you don’t let the compiler ingnore the result you
calculate in the loop ie use it in some where after the loop. Or even
the lowest level optimization will optimize the test code off as
unnecessary code. And make sure the loop limit value is not trivially
known at compile time.
My test code results:
The a = 0 print out is used to make sure that the looped code will not
be optimized out.
Result with gcc 2.95.3
sami at voltage ~/prog/tests $ gcc -O3 loop_testing.c
sami at voltage ~/prog/tests $ ./a.out
a = 0
Running a = (a + 1) % 32 100000000 times
Took: 1 sec 340 ms
Begin: 1043810358.157 sec End: 1043810359.497 sec
a = 0
Running a = (a + 31) % 32 100000000 times
Took: 1 sec 356 ms
Begin: 1043810359.499 sec End: 1043810360.855 sec
a = 0
Running a = (a + 1) & 31 100000000 times
Took: 0 sec 266 ms
Begin: 1043810360.857 sec End: 1043810361.123 sec
a = 0
Running a = (a - 1) & 31 100000000 times
Took: 0 sec 263 ms
Begin: 1043810361.125 sec End: 1043810361.388 sec
Result with gcc 3.2.1
sami at voltage ~/prog/tests $ source /etc/profile
sami at voltage ~/prog/tests $ gcc -O3 loop_testing.c
sami at voltage ~/prog/tests $ ./a.out
a = 0
Running a = (a + 1) % 32 100000000 times
Took: 0 sec 693 ms
Begin: 1043811297.99 sec End: 1043811297.792 sec
a = 0
Running a = (a + 31) % 32 100000000 times
Took: 0 sec 675 ms
Begin: 1043811297.794 sec End: 1043811298.469 sec
a = 0
Running a = (a + 1) & 31 100000000 times
Took: 0 sec 273 ms
Begin: 1043811298.471 sec End: 1043811298.744 sec
a = 0
Running a = (a - 1) & 31 100000000 times
Took: 0 sec 269 ms
Begin: 1043811298.746 sec End: 1043811299.15 sec
Oh and now I shut up. ;)On Wednesday 29 January 2003 03:48, Glenn Maynard wrote:
On Wed, Jan 29, 2003 at 03:16:51AM +0200, Sami N??t?nen wrote: