JavaScript中的精确浮点运算

时间:2012-04-27 16:12:02

标签: javascript floating-point modulus

我在JavaScript中创建数字微调器小部件,基本上模仿了webkit中的数字字段。

当您更改数字时,需要检查该值是否不仅在可接受的范围内,还包括它的步骤:

<input type="number" min="0" max="100" step="1" />

如果用户输入5.5,该字段会将此字符截断为低于该值的最接近的步骤,在本例中为5

对于2的步骤,如果用户输入5.5,则结果为4

我计划用于此计算的等式如下所示:

...code...
_checkStep: function (val) {
    val ret,
        diff,
        moddedDiff;
    diff = val - this._min;
    moddedDiff = diff % this._step;
    ret = val - moddedDiff;
    return ret;
},
//set elsewhere
_min,
_step,
...more code...

虽然出于测试目的,您可以简单地使用它:

function checkStep(val, min, step) {
    var ret,
        diff,
        moddedDiff;
    diff = val - min;
    moddedDiff = diff % step;
    ret = val - moddedDiff;
    return ret;
}

这适用于整数和更大的值,但由于JavaScript如何处理浮点数,我遇到了小数问题。

例如:

checkStep(0.5, 0, 0.1) //returns 0.4, 0.5 is expected

在分析每一行时,结果是JavaScript中的0.5 % 0.1返回0.09999999999999998

可以做些什么来使这个功能更准确*?


*准确的说它适用于0.01及以上的增量。

2 个答案:

答案 0 :(得分:1)

您可以尝试确保步长大于1(通过重复乘以10),然后执行模数,然后缩小到原始值。例如:

function checkStep(val, min, step) {
  var ret,
    diff,
    moddedDiff;
  var pows = 0;
  while( step < 1 ) { // make sure step is > 1
    step *= 10;
    val *= 10;
    min *= 10;
    pows++;
  }
  diff = val - min;
  moddedDiff = diff % step;
  ret = val - moddedDiff;
  return ret / Math.pow( 10, pows );
}

这适用于您提供的示例,但我无法保证它适用于所有内容。请参阅这里的jsfiddle:

http://jsfiddle.net/bCTL6/2/

答案 1 :(得分:-1)

没有绝对保证准确的浮点计算。改为使用整数计算。在你的0.1例子中,你可以用整数计算“0.1”的数量,在用户的最后一位数字之前直观地加点。