获取数模数范围以使返回值介于最小和最大范围值之间的正确方法是什么?

时间:2018-04-27 03:14:02

标签: javascript leaflet modulo discrete-mathematics number-theory

我正在查看传单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 :(得分:2)

  

...是否会错过原始表达所涵盖的任何测试用例?

是。对于 x 的大多数值,您将获得小于最小范围范围[0] 的错误值。

这是因为% multiplicative operator返回一个余数,而不是一个正确的模数,例如:

-1 % 12

返回-1而不是1(见JavaScript % (modulo) gives a negative result for negative numbers),因此使用了复杂的:

((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>
&#13;
&#13;
&#13;