Why does modulus operator return fractional number in javascript?

Why does 49.90 % 0.10 in JavaScript return 0.09999999999999581 ? I expected it to be 0.


Because JavaScript uses floating point math which always leads to rounding errors.

If you need an exact result with two decimal places, multiply your numbers with 100 before the operation and then divide again afterwards:

var result = ( 4990 % 10 ) / 100;

Round if necessary.


Javascript's Number is using "IEEE double-precision" to store the values. They are incapable of storing all decimal numbers exactly. The result is not zero because of round-off error when converting the decimal number to binary.

49.90 = 49.89999999999999857891452848...
 0.10 =  0.10000000000000000555111512...

Thus floor(49.90 / 0.10) is only 498, and the remainder will be 0.09999....


It seems that you are using numbers to store amount of dollars. Don't do this, as floating point operations propagate and amplify the round-off error. Store the number as amount of cents instead. Integer can be represented exactly, and 4990 % 10 will return 0.


我将把它留在这里供将来参考,但这里有一个方便的函数,可以更精确地处理涉及浮点数的余数(因为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);
  }

$(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);
  });
});
<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>
链接地址: http://www.djcxy.com/p/27464.html

上一篇: 如何在JavaScript中格式化一个浮点数?

下一篇: 为什么模数运算符在javascript中返回小数?