Skip to content

Instantly share code, notes, and snippets.

@Jeff-Russ
Last active October 31, 2018 05:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Jeff-Russ/0ca7e6c936626746acae0008e627da4d to your computer and use it in GitHub Desktop.
Save Jeff-Russ/0ca7e6c936626746acae0008e627da4d to your computer and use it in GitHub Desktop.
C/C++ function to wrap out-of-bounds numbers to a specific range (modulo with an offset)
/* wrap_to_range() is similar to modulo but, instead of wrapping back to zero, wraps
back to specified range closer to the top (what the modulo value would be).
It was created for musical keyboard to handle a note command that is too high to be
played in order to handle that event that so that the specified note is still played
just in a different octave (the highest octave possible).
For those where that useage doesn't ring true, imagine a clock function (in 24 hour
time) where if 24:01 is attempted to be set (an invalid time) it is adjusted to 23:01.
The same 23:01 would be returned if 25:01 or 26:01 are attempted.
The second arg is the max (allowed) value
The third arg is the width of the wrapping
For unsigned results the 3rd arg CANNOT be greater than max (2nd arg) */
long long wrap_to_range(long long val, long long max, long long width)
{
if (val <= max) return val;
long long offset = max - width;
val -= offset;
val = val % width;
val += offset;
return val;
}
@Jeff-Russ
Copy link
Author

A version that wraps the integer component, keeping floating point component where it is:

double wrapToI(double in, double min, double max)
{
    if (in > max) {
        do in -= 1.0;           // OVER: decrement until
        while ( in > max );     //       no longer over max
        if (in < min) in = max; // Now it's UNDER! return null?
        return in;
    } else if (in < min) {
        do in += 1.0;           // UNDER: increment until
        while ( in < min );     //        no longer under min.
        if (in > max) in = max; // now it's OVER! return null?
        return in;
    }
    else return in;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment