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

- 1,498
- 3
- 17
- 29

- 4,348
- 4
- 40
- 59
-
3See [Is JavaScript's Math broken? ](http://stackoverflow.com/questions/588004/is-javascripts-math-broken). – Matthew Flaschen Oct 19 '10 at 08:31
-
[See: Python modulo on floats](https://stackoverflow.com/questions/14763722/python-modulo-on-floats) (different language, but the issue -- floating point error -- is the same) – user202729 Jul 27 '18 at 13:12
8 Answers
Because JavaScript uses floating point math which can lead 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.

- 13,051
- 4
- 61
- 89

- 321,842
- 108
- 597
- 820
-
3+1 In many financial systems, this is the way currency are handled internally (multiplied by 100) and when rendered, the currency rules are applied. – Mic Oct 19 '10 at 08:39
-
Ah, nice trick, avoiding the floats by turning the number into an integer beforehand. So beautifully easy. – Avatar Aug 05 '16 at 20:20
-
This is also called "fixed point arithmetic" since you always have 2 (or N) decimals. – Aaron Digulla Aug 09 '16 at 15:06
-
1Thank for your insight, but this approach wasn't perfect. `(40.55 * 100 %1000)/100` returns 0.549999... instead of 0.55. – Hiroki Sep 25 '18 at 23:53
-
2@hiroki the answer says to "round if necessary", I would add in case you need it toFixed(2) on the output. toFixed already rounds. – Simone-Cu Apr 28 '20 at 07:16
I'll just leave this here for future reference, but here is a handy function that can more precisely handle Remainder (since JS doesn't have a modulo operator) involving floats.
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>

- 25,646
- 9
- 66
- 78
-
2This answer is underrated. While a bit more verbose, the script is much more robust. – Domino Jan 12 '16 at 19:00
-
Might look scary, but take the time to read this one. It works very well. Only thing I would add: if you care about negative numbers, javascript modulo doesn't handle them as you would expect. You can change the return to: `return (((valInt % stepInt) + stepInt) % stepInt) / Math.pow(10, decCount)` – James Jul 31 '19 at 09:32
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.
Cause
Floating point can't store all decimal values exactly. So when using floating point formats there will always be rounding errors on the input values. The errors on the inputs of course results on errors on the output. In case of a discrete function or operator there can be a big difference on the output around the point where the function or operator is discrete. The modula operator is discrete and your case is clearly an example of this problem.
Input and output for floating point values
So, when using floating point variables, you should always be aware of this. And whatever output you want from a calculation with floating points should always be formatted/conditioned before displaying with this in mind.
When only continuous functions and operators are used, rounding to the desired precision often will do (don't truncate). Standard formatting features used to convert floats to string will usually do this for you.
To have a correct output based on expected precision of inputs and desired precision of output, you should also
- Round inputs to the expected precision or make sure no values can be entered with higher precision.
- Add a small value to the outputs before rounding/formatting them which is smaller than or equal to 1/4 of the desired precision and bigger than the maximum expected error caused by rounding errors on input and during calculation. If that is not possible the combination of the precision of the used data type isn't enough to deliver the desired output precision for your calculation.
These 2 things are often not done and in most cases the differences caused by not doing them are too small to be important for most users, but I already had a project where output wasn't accepted by the users without those corrections.
Discrete functions or operators (like modula)
When discrete operators or functions are involved, extra corrections might be required to make sure the output is as expected. Rounding and adding small corrections before rounding can't solve the problem.
A special check/correction on intermediate calculation results, immediately after applying the discrete function or operator might be required.
Specific case of this question
In this case, you expect input with a certain precision, so it is possible to correct output for impact of rounding errors which are a lot smaller than the desired precision.
If we say the precision of your data type is e.
Your input will not be stored as the values a and b you entered, but as a*(1+/-e) and b*(1+/-e)
The result of a division a*(1+/-e) by b*(1+/-e) would result in (a/b)(1+/-2e).
The modula function has to truncate the result and multiply again.
So the result will be (a/bb)(1+/-3e) = a(1+/-3e) resulting in an error of a*3e.
The mod adds a*e to the possible error of a*3e because of the subtraction of 2 values with a possible errors of a*3e and a*e.
So you should check that the total possible error a*4e is smaller than the desired precision and if that condition is met and the result differs no more from b than that maximum possible error, you can safely replace it by 0.
Better avoid having the problem
It is often more efficient to avoid these problems by using data types (integer or fixed point formats) for calculations like this which can store the expected input without rounding errors. An example of that is that you should never use floating point values for financial calculations.

- 829
- 6
- 10
Take a look at floating points and its disadvantages - a number like 0.1
can't be saved correctly as floating point, so there will always be such problems. Take your numbers *10 or *100 and do the calculations with integers instead.

- 2,453
- 4
- 24
- 28

- 51,017
- 10
- 98
- 115
http://en.wikipedia.org/wiki/Modulo_operation Don't be angry modulo is used with integers ^^ So floating values occure some errors.

- 18,071
- 6
- 54
- 69
Hopefully this is helpful to someone:
let asBuffer = new ArrayBuffer(8);
let asInt = new Uint32Array(asBuffer );
let asFloat = new Float32Array(asBuffer );
asFloat.set([49.9,.1]);
asInt.set([asFloat[0]/asFloat[1], asFloat[0]%asFloat[1]]);
Result
asInt Uint32Array(2) [499, 0, buffer: ArrayBuffer(8), byteLength: 8, byteOffset: 0, length: 2, Symbol(Symbol.toStringTag): 'Uint32Array']
//In general I'm moving more and more towards
//Using typed arrays to store values in JS.

- 61
- 2
This is not a perfect answer but it works.
function format_float_bug(num)
{
return parseFloat( num.toFixed(15) );
}
you can use as follows,
format_float_bug(4990 % 10);
because below number (49.89999999999999857891452848) first 15 decimal places are like 9999999

- 11
-
This doesn't work at all, and your example call doesn't even use floats! – Domino Jan 12 '16 at 18:59
-
Using "toFixed" and "parseFloat" is not so bad. You might define your number of decimals in "toFixed" function. You should set 2 arguments in your function and count decimal number from 2nd argument, that is the modulo – FragBis Jun 27 '22 at 02:14
-
const fmod = (x, y) => { let expY = y.toString().split('.'); let nbDec = expY.length > 1 ? expY[1].length : 0; return parseFloat( (x % y).toFixed(nbDec) ); }; – FragBis Jun 27 '22 at 02:21