Я просматривал буклет js-кода. Существует функция wrapNum.
// @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;
}
Таким образом, они просто пытаются найти номер по модулю, чтобы число лежало между данным диапазоном min - max.
Вместо использования выражения ((x - min) % d + d) % d + min
если я напишу ((x - min) % d) + min
, пропустит ли какой-либо тестовый пример, который покрыт оригинальным выражением?
... будет ли пропустить какой-либо тестовый пример, который покрывается оригинальным выражением?
Да. Вы получите неверные значения для большинства значений x, которые меньше минимального диапазона диапазона [0].
Это связано с тем, что оператор умножения %
возвращает остаток, а не соответствующий по модулю, например
-1 % 12
возвращает -1, а не 1 (см. JavaScript% (по модулю) дает отрицательный результат для отрицательных чисел), следовательно, использование свернутого:
((x - min) % d + d) % d
который получает правильное значение по модулю. Некоторые коды воспроизведения:
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>