# javascript decimal - How to deal with floating point number precision in JavaScript?

From the Floating-Point Guide:

What can I do to avoid this problem?That depends on what kind of calculations you’re doing.

- If you really need your results to add up exactly, especially when you work with money: use a special decimal datatype.
- If you just don’t want to see all those extra decimal places: simply format your result rounded to a fixed number of decimal places when displaying it.
- If you have no decimal datatype available, an alternative is to work with integers, e.g. do money calculations entirely in cents. But this is more work and has some drawbacks.

Note that the first point only applies if you really need specific precise *decimal* behaviour. Most people don't need that, they're just irritated that their programs don't work correctly with numbers like 1/10 without realizing that they wouldn't even blink at the same error if it occurred with 1/3.

If the first point really applies to you, use BigDecimal for JavaScript, which is not elegant at all, but actually solves the problem rather than providing an imperfect workaround.

I have the following dummy test script:

```
function test(){
var x = 0.1 * 0.2;
document.write(x);
}
test();
```

This will print the result `0.020000000000000004`

while it should just print `0.02`

(if you use your calculator). As far as I understood this is due to errors in the floating point multiplication precision.

Does anyone have a good solution so that in such case I get the correct result `0.02`

? I know there are functions like `toFixed`

or rounding would be another possibility, but I'd like to really have the whole number printed without any cutting and rounding. Just wanted to know if one of you has some nice, elegant solution.

Of course, otherwise I'll round to some 10 digits or so.

For the mathematically inclined: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

The recommended approach is to use correction factors (multiply by a suitable power of 10 so that the arithmetic happens between integers). For example, in the case of `0.1 * 0.2`

, the correction factor is `10`

, and you are performing the calculation:

```
> var x = 0.1
> var y = 0.2
> var cf = 10
> x * y
0.020000000000000004
> (x * cf) * (y * cf) / (cf * cf)
0.02
```

A (very quick) solution looks something like:

```
var _cf = (function() {
function _shift(x) {
var parts = x.toString().split('.');
return (parts.length < 2) ? 1 : Math.pow(10, parts[1].length);
}
return function() {
return Array.prototype.reduce.call(arguments, function (prev, next) { return prev === undefined || next === undefined ? undefined : Math.max(prev, _shift (next)); }, -Infinity);
};
})();
Math.a = function () {
var f = _cf.apply(null, arguments); if(f === undefined) return undefined;
function cb(x, y, i, o) { return x + f * y; }
return Array.prototype.reduce.call(arguments, cb, 0) / f;
};
Math.s = function (l,r) { var f = _cf(l,r); return (l * f - r * f) / f; };
Math.m = function () {
var f = _cf.apply(null, arguments);
function cb(x, y, i, o) { return (x*f) * (y*f) / (f * f); }
return Array.prototype.reduce.call(arguments, cb, 1);
};
Math.d = function (l,r) { var f = _cf(l,r); return (l * f) / (r * f); };
```

In this case:

```
> Math.m(0.1, 0.2)
0.02
```

I definitely recommend using a tested library like SinfulJS

You are looking for an `sprintf`

implementation for JavaScript, so that you can write out floats with small errors in them (since they are stored in binary format) in a format that you expect.

Try javascript-sprintf, you would call it like this:

```
var yourString = sprintf("%.2f", yourNumber);
```

to print out your number as a float with two decimal places.

You may also use Number.toFixed() for display purposes, if you'd rather not include more files merely for floating point rounding to a given precision.

This function will determine the needed precision from the multiplication of two floating point numbers and return a result with the appropriate precision. Elegant though it is not.

```
function multFloats(a,b){
var atens = Math.pow(10,String(a).length - String(a).indexOf('.') - 1),
btens = Math.pow(10,String(b).length - String(b).indexOf('.') - 1);
return (a * atens) * (b * btens) / (atens * btens);
}
```

You just have to make up your mind on how many decimal digits you actually want - can't have the cake and eat it too :-)

Numerical errors accumulate with every further operation and if you don't cut it off early it's just going to grow. Numerical libraries which present results that look clean simply cut off the last 2 digits at every step, numerical co-processors also have a "normal" and "full" lenght for the same reason. Cuf-offs are cheap for a processor but very expensive for you in a script (multiplying and dividing and using pov(...)). Good math lib would provide floor(x,n) to do the cut-off for you.

So at the very least you should make global var/constant with pov(10,n) - meaning that you decided on the precision you need :-) Then do:

```
Math.floor(x*PREC_LIM)/PREC_LIM // floor - you are cutting off, not rounding
```

You could also keep doing math and only cut-off at the end - assuming that you are only displaying and not doing if-s with results. If you can do that, then .toFixed(...) might be more efficient.

If you are doing if-s/comparisons and don't want to cut of then you also need a small constant, usually called eps, which is one decimal place higher than max expected error. Say that your cut-off is last two decimals - then your eps has 1 at the 3rd place from the last (3rd least significant) and you can use it to compare whether the result is within eps range of expected (0.02 -eps < 0.1*0.2 < 0.02 +eps).

The result you've got is correct and fairly consistent across floating point implementations in different languages, processors and operating systems - the only thing that changes is the level of the inaccuracy when the float is actually a double (or higher).

0.1 in binary floating points is like 1/3 in decimal (i.e. 0.3333333333333... forever), there's just no accurate way to handle it.

If you're dealing with floats *always* expect small rounding errors, so you'll also always have to round the displayed result to something sensible. In return you get very very fast and powerful arithmetic because all the computations are in the native binary of the processor.

Most of the time the solution is not to switch to fixed-point arithmetic, mainly because it's much slower and 99% of the time you just don't need the accuracy. If you're dealing with stuff that does need that level of accuracy (for instance financial transactions) Javascript probably isn't the best tool to use anyway (as you've want to enforce the fixed-point types a static language is probably better).

You're looking for the elegant solution then I'm afraid this is it: floats are quick but have small rounding errors - always round to something sensible when displaying their results.

Surprisingly, this function has not been posted yet although others have similar variations of it. It is from the MDN web docs for Math.round(). It's concise and allows for varying precision.

```
function precisionRound(number, precision) {
var factor = Math.pow(10, precision);
return Math.round(number * factor) / factor;
}
```

console.log(precisionRound(1234.5678, 1)); // expected output: 1234.6

console.log(precisionRound(1234.5678, -1)); // expected output: 1230

```
var inp = document.querySelectorAll('input');
var btn = document.querySelector('button');
btn.onclick = function(){
inp[2].value = precisionRound( parseFloat(inp[0].value) * parseFloat(inp[1].value) , 5 );
};
//MDN function
function precisionRound(number, precision) {
var factor = Math.pow(10, precision);
return Math.round(number * factor) / factor;
}
```

```
button{
display: block;
}
```

```
<input type='text' value='0.1'>
<input type='text' value='0.2'>
<button>Get Product</button>
<input type='text'>
```

0.6 * 3 it's awesome!)) For me this works fine:

```
function dec( num )
{
var p = 100;
return Math.round( num * p ) / p;
}
```

Very very simple))

Try my chiliadic arithmetic library, which you can see here. If you want a later version, I can get you one.

**Problem**

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 big differences on the output around the point where the function or operator is discrete.

**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.

Because the rounding adds an error which can cause the total error to be more then half of the desired precision, the output should be corrected based on expected precision of inputs and desired precision of output. You should

- 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 usually 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.
For a specific case (modula operator), see my answer on question: Why does modulus operator return fractional number in javascript?

**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.

```
You can use library https://github.com/MikeMcl/decimal.js/.
it will help lot to give proper solution.
javascript console output 95 *722228.630 /100 = 686117.1984999999
decimal library implementation
var firstNumber = new Decimal(95);
var secondNumber = new Decimal(722228.630);
var thirdNumber = new Decimal(100);
var partialOutput = firstNumber.times(secondNumber);
console.log(partialOutput);
var output = new Decimal(partialOutput).div(thirdNumber);
alert(output.valueOf());
console.log(output.valueOf())== 686117.1985
```

You are right, the reason for that is limited precision of floating point numbers. Store your rational numbers as a division of two integer numbers and in most situations you'll be able to store numbers without any precision loss. When it comes to printing, you may want to display the result as fraction. With representation I proposed, it becomes trivial.

Of course that won't help much with irrational numbers. But you may want to optimize your computations in the way they will cause the least problem (e.g. detecting situations like `sqrt(3)^2)`

.

I had a nasty rounding error problem with mod 3. Sometimes when I should get 0 I would get .000...01. That's easy enough to handle, just test for <= .01. But then sometimes I would get 2.99999999999998. OUCH!

BigNumbers solved the problem, but introduced another, somewhat ironic, problem. When trying to load 8.5 into BigNumbers I was informed that it was really 8.4999… and had more than 15 significant digits. This meant BigNumbers could not accept it (I believe I mentioned this problem was somewhat ironic).

Simple solution to ironic problem:

```
x = Math.round(x*100);
// I only need 2 decimal places, if i needed 3 I would use 1,000, etc.
x = x / 100;
xB = new BigNumber(x);
```

This works for me:

```
function round_up( value, precision ) {
var pow = Math.pow ( 10, precision );
return ( Math.ceil ( pow * value ) + Math.ceil ( pow * value - Math.ceil ( pow * value ) ) ) / pow;
}
round_up(341.536, 2); // 341.54
```

while adding two float value its never give the precise values so we need to fixed this to certain number that will help us to compare.

console.log((parseFloat(0.1) + parseFloat(0.2)).toFixed(1) == parseFloat(0.3).toFixed(1));