0

I've got a weird maths/rounding problem in Javascript.

The snippet below is a very basic example of the code I'm running. Obviously it's not this exact code, but I'm taking a decimal value from a text box, working out a percentage and taking this away from one.

var ten = "10";
var eight = "8";

alert(1 - (eight/ten));

The problem is the answer is 0.2 but the calculation returns 0.1999999999999996. Yet if I do 1 + (eight/ten) 1.8 is returned. What is going on?

Phil Hale
  • 3,453
  • 2
  • 36
  • 50
  • 1
    Does no-one notice this question is about why + and - treat the number differently rather then how floating points work? – Raynos Oct 28 '10 at 10:33
  • @Raynos the problem *is* floating point arithmetic. Not the `+` or `-` - it happens that `1 -0.8` leads to a floating point number with inaccirate representation. Yet `1 + 0.8` does not. Yet if you do `0.1 + 0.2` you'd also get an inaccurate representation. It's not the operation, it's the result. And the result is a floating point number. – VLAZ Apr 12 '22 at 07:42

4 Answers4

3

It's because of the way floating point numbers are represented.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
3

Welcome to the world of floating-point numbers!

Computers don't actually work with decimal numbers--i.e. numbers in base ten, the way we use them in normal life. They work with binary numbers, and that includes floating-point numbers. They're represented in binary as well, and that means that "number of decimal places" is not always a meaningful property of a floating-point number.

For instance, a floating-point number cannot exactly represent 0.1, and you'll get something like 0.1000000001 if you try to use it in your code. The exact value you get varies by implementation, and is not correctable by subtracting the difference, as the computer can't tell that there is a difference--that's as close as it can get to 0.1.

(Stole most of this answer from a previous answer of mine.)

Community
  • 1
  • 1
Jonathan Grynspan
  • 43,286
  • 8
  • 74
  • 104
0

I have the same result on my android device which means your device or computer works with 64 bits floating point representation. For correct result, you must limit displaying your result to 15 digits. I found this workaround : running :

var res = 1 - 0.8; 
var roundedRes = parseFloat(res.toPrecision(15) ) ; 
alert ("res="+res+"\n" + "roundedRes="+roundedRes); 

ouputs : res=0.19999999999999996 roundedRes=0.2

-1

JavaScript use binary floating point for representation of numbers like 1/2,1/8...1/1024. But decimal fractions which we mostly use are represented in form 1/10,1/100...

This will not be a problem with JavaScript only but with all languages that use binary floating point representation.

VLAZ
  • 26,331
  • 9
  • 49
  • 67
Sohail Arif
  • 279
  • 2
  • 9
  • Could you please elaborate more your answer adding a little more description about the solution you provide? – abarisone Jun 23 '15 at 12:14