tags:

views:

95

answers:

1

I need to write a function that returns a value within an interval [a..b] after applying a delta.

void foo(a, b, val, delta);

Example1: value = foo(0, 360, 120, -240); value: 240

Example 2: value = foo(360, 0, 60, 340); value: 40

I have been able to code this behavior but I would like to compare my implementation with a (most likely) more optimal solution.

+1  A: 

I typed up a few lines in Perl. Seemed to work on the few examples I tested.

print ((($val + $delta) % abs($a - $b)) + ($a<$b?$a:$b));

I add the delta to the value, mod it by the absolute difference between A and B (guaranteeing the value to be within range), and then add the smaller value back in (in case the range wasn't between some number and 0). The final term is an if-then shorthand technique, where if the condition is true, it takes the first value, and if not, it takes the 2nd.

Hopefully I understood what you were wanting to do correctly.

EDIT: On second look, I think the above equation does not handle the boundaries correctly if neither side is 0. After rethinking, I believe below to be better:

print (((($val + $delta) % ($a>$b?$a:$b) - ($a<$b?$a:$b)) % abs($a-$b)) + ($a<$b?$a:$b));

Before, adding say 20 to the lower value, ended up adding 40 to the end result. I was accidentally adding 20 twice. Once in the last term, and once because I was modding by a value that was 20 smaller (which adds 20 to the remainder). I couldn't take off the last term, because then it wouldn't be in range, and I couldn't remove the subtraction from the mod, as that could result in a value over the top end of the interval. Instead, I had to subtract the lower value from the initial addition to compensate. This however can only be subtracted from a positive value to be correct, so I modded it by the higher value, making it positive, and making sure the modded value is unchanged (taking the absolute value would change what was being modded for later).

FModa3
Uh, this is a C++ question.
GMan
The important thing was the algorithm. I used perl to try it out fast and easy. If he needs C++, the above line is easily translatable.
FModa3