为什么模数运算符在javascript中返回小数?

Edg*_*gar 30 javascript floating-point modulus

为什么49.90 % 0.10在JavaScript中返回0.09999999999999581?我预计它会是0.

Aar*_*lla 51

因为JavaScript使用浮点数学,这总是会导致舍入错误.

如果您需要两位小数的精确结果,请100在操作前将数字相乘,然后再划分:

var result = ( 4990 % 10 ) / 100;
Run Code Online (Sandbox Code Playgroud)

必要时轮换.

  • +1在许多金融系统中,这是货币在内部处理的方式(乘以100),在提交时,应用货币规则. (2认同)
  • @hiroki,答案是“如有必要,请舍入”,如果您需要它,我会在输出上添加到Fixed(2)。已修复。 (2认同)

ken*_*ytm 18

Javascript的Number使用"IEEE双精度"来存储值.它们无法准确存储所有十进制数.由于将十进制数转换为二进制时的舍入误差,结果不为零.

49.90 = 49.89999999999999857891452848...
 0.10 =  0.10000000000000000555111512...
Run Code Online (Sandbox Code Playgroud)

因此,楼层(49.90/0.10)仅为498,其余为0.09999 ....


看来你正在使用数字存储金额.不要这样做,因为浮点运算会传播并放大舍入误差.将数字存储为美分金额.整数可以准确表示,并4990 % 10返回0.


The*_*One 13

我将把它留在这里供将来参考,但是这里有一个方便的函数,可以更精确地处理余数(因为JS没有模运算符)涉及浮点数.

  function floatSafeRemainder(val, step){
    var valDecCount = (val.toString().split('.')[1] || '').length;
    var stepDecCount = (step.toString().split('.')[1] || '').length;
    var decCount = valDecCount > stepDecCount? valDecCount : stepDecCount;
    var valInt = parseInt(val.toFixed(decCount).replace('.',''));
    var stepInt = parseInt(step.toFixed(decCount).replace('.',''));
    return (valInt % stepInt) / Math.pow(10, decCount);
  }
Run Code Online (Sandbox Code Playgroud)

$(function() {
  
  
  function floatSafeModulus(val, step) {
    var valDecCount = (val.toString().split('.')[1] || '').length;
    var stepDecCount = (step.toString().split('.')[1] || '').length;
    var decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount;
    var valInt = parseInt(val.toFixed(decCount).replace('.', ''));
    var stepInt = parseInt(step.toFixed(decCount).replace('.', ''));
    return (valInt % stepInt) / Math.pow(10, decCount);
  }
  
  
  $("#form").submit(function(e) {
    e.preventDefault();
    var safe = 'Invalid';
    var normal = 'Invalid';
    var var1 = parseFloat($('#var1').val());
    var var2 = parseFloat($('#var2').val());
    if (!isNaN(var1) && !isNaN(var2)) {
      safe = floatSafeModulus(var1, var2);
      normal = var1 % var2
    }
    $('#safeResult').text(safe);
    $('#normalResult').text(normal);
  });
});
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="form" novalidate>
  <div>
    <input type="number" id="var1">%
    <input type="number" id="var2">
  </div>
  <div>safe: <span id="safeResult"></span><div>
  <div>normal (%): <span id="normalResult"></span></div>
  <input type="submit" value="try it out">
</form>
Run Code Online (Sandbox Code Playgroud)

  • 这个答案被低估了。虽然更加冗长,但脚本更加健壮。 (2认同)