Как правильно получить числовой диапазон по модулю так, чтобы возвращаемое значение находилось между минимальным и максимальным значениями диапазона? - PullRequest
0 голосов
/ 27 апреля 2018

Я проверял код 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;
}

Итак, они просто пытаются найти диапазон чисел по модулю так, чтобы число находилось между заданным минимальным и максимальным диапазоном.

Вместо использования ((x - min) % d + d) % d + min выражения, если я напишу ((x - min) % d) + min, пропустит ли это какой-либо тестовый пример, охватываемый исходным выражением?

1 Ответ

0 голосов
/ 27 апреля 2018

… будет ли пропущен любой контрольный пример, охватываемый исходным выражением?

Да. Вы получите неверные значения для большинства значений x , которые меньше минимального диапазона range [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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...