Reputation: 17217
i'm attempting to build a tiny (or perhaps not so tiny) formula that will contain numbers between a set min and max, but also loop these numbers so they are not clipped if they are outside of the range. so far, this is what i have.
min1 = 10
max1 = 90
val1 = 92
//will make 11, which is what i want since it loops
formula: min(max(min1,min(val1,max1)),mod(val1,max1)+min1)
however, i'd like it to loop the other direction also, so that if val1 is 5, which is -5 outside of min1, it will become 86.
another problem i'm running into is that
max1 % max1 != max1
as i want it to, since the max is part of the range
trying to be clear, here are some examples of desired output based on a range with looping
min1 = 10
max1 = 90
----------------------------------------------
val1 = 30 //within range: stays as 30
val1 = 90 //within range: stays as 90
val1 = -6 //below range: loops to becomes 75
val1 = 98 //above range: loops to becomes 17
val1 = 91 //above range: loops to becomes 10
i'd like not to resort to using a series of if/else statements, but one would be fine if it's absolutely required. is that even possible?
Upvotes: 13
Views: 6743
Reputation: 19114
Sorry. Deleted previous answer. Try this one:
((val-min)%(max-min)+max-min)%(max-min)+min
EDIT: if you want max to be a valid value instead of overflowing to min, replace max by max+1 in all 3 places.
Upvotes: 1
Reputation: 13783
int loop(int val, int min, int max)
{
int p = max-min+1;
int mod = (val-min)%p;
if(mod<0)
mod += p;
return min+mod;
}
Upvotes: 5
Reputation: 5706
Mathematically, you should be able to do something like this:
((val-min) `mod` (max-min+1)) + min
Move your range down to be zero-based, clip off the high end, and shift it back to the right range. Unfortunately, the % operator in C gives negative results for negative numbers. So:
3 % 10 => 3
13 % 10 => 3
-3 % 10 => -3
-13 % 10 => -3
So to get rid of these negatives, we need one extra modulo:
((val-min)%(max-min+1) + (max-min+1)) % (max-min+1) + min
Upvotes: 4