Reputation: 355
I was checking out the leaflet js code. There is a wrapNum function.
// @function wrapNum(num: Number, range: Number[], includeMax?: Boolean): Number
// Returns the number `num` modulo `range` in such a way so it lies within
// `range[0]` and `range[1]`. The returned value will be always smaller than
// `range[1]` unless `includeMax` is set to `true`.
function wrapNum(x, range, includeMax) {
var max = range[1],
min = range[0],
d = max - min;
return x === max && includeMax ? x : ((x - min) % d + d) % d + min;
}
So, they are simply trying to find a number modulo range so that the number lies between the given min - max range.
Instead of using ((x - min) % d + d) % d + min
expression if I write ((x - min) % d) + min
, will that miss any test case that is covered by original expression?
Upvotes: 1
Views: 5419
Reputation: 147413
…will that miss any test case that is covered by original expression?
Yes. You will get incorrect values for most values of x that are less than the range minimum range[0].
That is because the %
multiplicative operator returns a remainder, not a proper modulo, e.g.
-1 % 12
returns -1, not 1 (see JavaScript % (modulo) gives a negative result for negative numbers) hence the use of the convoluted:
((x - min) % d + d) % d
which gets the correct modulo value. Some play code:
function wrapNum0(x, range, includeMax) {
var max = range[1],
min = range[0],
d = max - min;
return x === max && includeMax ? x : ((x - min) % d + d) % d + min;
}
function wrapNum1(x, range, includeMax) {
var max = range[1],
min = range[0],
d = max - min;
return x === max && includeMax ? x : ((x - min) % d) + min;
}
function doCalc(form) {
var num = +form.num.value;
var range = form.range.value.split(',').map(Number);
var includeMax = form.includeMax.checked;
form.result0.value = wrapNum0(num, range, includeMax);
form.result1.value = wrapNum1(num, range, includeMax);
}
<form onsubmit="event.preventDefault();doCalc(this); return false;">
<input value="3" name="num">Value<br>
<input value="5,10" name="range">Range (<em>min,max</em>)<br>
<input type="checkbox" name="includeMax">Inclue max?<br>
<input readonly name="result0">Original (wrapNum0)<br>
<input readonly name="result1">Modified (wrapNum1)<br>
<input type="reset"><button>Do calc</button>
</form>
Upvotes: 2