Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Math Looping Between Min and Max Using Mod?

Tags:

math

module

range

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?

like image 760
Chunky Chunk Avatar asked Jun 16 '10 22:06

Chunky Chunk


3 Answers

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
like image 26
Karmastan Avatar answered Nov 11 '22 07:11

Karmastan


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;
}
like image 98
Rotsor Avatar answered Nov 11 '22 05:11

Rotsor


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.

like image 1
Pavel Radzivilovsky Avatar answered Nov 11 '22 06:11

Pavel Radzivilovsky