I'm trying to create a function to underflow a number back up or overflow a number back down into a specified range mathematically. I think I was able to get this to work when the numbers are all positive (taking out Math.Abs
(used to positivify negative numbers)) but ranges which go negative or negative values fail. I want to solve this with Maths but can't figure out what I'm doing wrong!
This is my current implementation of the failing function:
/// <summary>
/// Wraps a value within the specified range, overflowing or underflowing as necessary.
/// </summary>
/// <param name="value">The number to wrap.</param>
/// <param name="minimumValue">The minimum value in the range.</param>
/// <param name="length">The number of values in the range to wrap across.</param>
/// <returns>The <paramref name="value"/> wrapped to the specified range.</returns>
/// <exception cref="ArgumentException">Thrown if <paramref name="length"/> is <c>0</c>.</exception>
public static int Wrap(this int value, int minimumValue, int length)
{
if (length == 0)
throw new ArgumentException($"{nameof(length)} must not be 0 in order to produce a range to wrap across.");
else
{
var absoluteModulus = System.Math.Abs((value - minimumValue) % length);
return (value < 0 ? length - absoluteModulus : absoluteModulus) + minimumValue;
}
}
Here's some test data and results for the current implementation:
value | minimumValue | length | expected | actual | Comment |
---|---|---|---|---|---|
128 | 256 | 128 | 256 | 256 | Pass |
255 | 256 | 256 | 511 | 257 | Modulo is underflowing backwards! |
-3 | 1 | 2 | 1 | 3 | Somehow underflowing out of range! |
-4 | 0 | 2 | 0 | 2 | Again, underflowing out of range! |
63 | 128 | 384 | 447 | 193 | 128 - 63 == 65, 384 - 65 == 319, 319 + 128 == 447, not 193‼ |
300 | 100 | 200 | 100 | 100 | This overflow works! |