tags:

views:

127

answers:

3

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?

A: 
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;
}
Rotsor
Why not just start out with `if (val == max) return max;`?
Jurily
Because he probably wants 170 to become 90 too. Anyway, both ways seem identically useless to me.
Rotsor
i'm terribly sorry. i've been misleading you since i had my looping logic screwed up. you noticed earlier but i didn't quite understand until now. 91 should be 10, not 11. 9 should become 90, etc. to make the loop correct.
TheDarkInI1978
Ok, removed that.
Rotsor
great! your solution works perfectly.
TheDarkInI1978
+1  A: 

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.

Pavel Radzivilovsky
Who uses two divisions instead of one? :)Also, 90 will become 10.
Rotsor
sorry pavel, i've edited my question because i had my looping logic confused.
TheDarkInI1978
@rotsor: int Modulo(int x, int y) { int answer = x % y; return answer < 0 ? answer + std::abs(y) : answer; }
Pavel Radzivilovsky
+1  A: 

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
Karmastan
This is exactly the thing me and Pavel are doing, but your solution does not check for val<min scenario.
Rotsor
Re Rotsor: that should fix it.
Karmastan