4

First question: In java script if we do.

0.2 + 0.1
=>0.30000000000000004

Because 0.2,0.1 are rounded off to different number and also the sum is rounded of to a different number This article explains the behind the scenes.I understand this but when i do.

0.3 + 0
=>0.3  

It shows 0.3 why? 0.3 cannot be exactly represented in binary right and it should be rounded to different number right?.
so the value of 0.3 + 0 should be the rounded number of 0.3 and the sum if needed?.

Second question:
when we do.

let x = 0.3

As 0.3 cannot be represented exactly in binary it is rounded of to another number but when you access the variable x why does it show 0.3 but not the actual rounded of number.

x
=>0.3

But when you do.

0.2 + 0.1
=>0.30000000000000004

It shows the actual rounded of number but not 0.3. Kindly explain.

  • "*0.3 cannot be exactly represented in binary right*" and yet `0.3` gives you `0.3` not something different (even though it's imprecise). The extra zero added won't really disturb the value already present. – VLAZ Feb 14 '22 at 07:56
  • Does javascript actually perform an addition in 0.3 + 0? ... maybe it short-circuits the zero – jsotola Feb 14 '22 at 08:00
  • @jsotola - It doesn't really matter whether it does the operation or not, it wouldn't affect the value stored for `0.3`. – T.J. Crowder Feb 14 '22 at 08:01
  • I got the answers while i was editing. Did not expect it would be this fast. – runtimeerror Feb 14 '22 at 08:55
  • @runtimeerror - **:-)** SO's a really active place. – T.J. Crowder Feb 14 '22 at 10:26

1 Answers1

5

The value you get when you add 0.1 and 0.2 and the value you get from the literal 0.3 are different values (neither of which is exactly 3/10ths, both of which are very near it). (Adding 0 doesn't matter, it doesn't change the value of the number it's being added to.) The one you get from 0.1 + 0.2 is just barely over 3/10ths; the one you get from 0.3 (if I recall correctly) is just under 3/10ths.

When converting a floating point number to text, JavaScript follows the common practice of only including as many digits as are required to differentiate it from the next nearest value the format can represent (details in the spec and in the academic paper the spec references). 0.3 doesn't need any additional digits for that differentiation, but 0.30000000000000004 does (I'm guessing to differentiate it from 0.3, but I don't actually know that).

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • it's hard to understand from those articles. At the moment there are lot of things in those articles which are beyond my scope of knowledge.But i would love if some one can explain it in simple way,with an example and step by step. – runtimeerror Feb 14 '22 at 09:01
  • @runtimeerror - The basic thing is literally just that when you get the string `"0.3"` for the number `0.3`, it's not precisely what the number is. It's just sufficient to ensure that converting the string back to a number will give you the same number. `0.3` IIRC is `0.299999999999998` (or something like that) but since that's what you get when you convert `"0.3"` back to number, that's the string that's used, for interaction with humans. `0.1 + 0.2` is displayed as `"0.30000000000000004"` because it needs to differentiate from `"0.3"`. – T.J. Crowder Feb 14 '22 at 09:19
  • isn't it wrong to show that way. because when you assign 0.3 as literal but under the hood it is stored as different number. when you retrieve, it doesn't show the actual stored value.This makes people think they are actually storing 0.3 but it is not. Doesn't this cause unnecessary bugs and confusion. – runtimeerror Feb 14 '22 at 09:56
  • 1
    @runtimeerror - Efficient floating point numbers are a compromise between precision, size, and runtime cost; [more here](https://stackoverflow.com/questions/588004/is-floating-point-math-broken). And yes, people are constantly running into trouble because they don't realize the limitations of the kind of floating point number they're using. Thankfully, in today's world with **lots** more memory and **much** faster processors than when the IEEE-754 binary64 format was defined, we're increasingly getting other options (including the relatively new IEEE-754 decimal128). JavaScript... – T.J. Crowder Feb 14 '22 at 10:09
  • 1
    ...will be getting a [decimal](https://github.com/tc39/proposal-decimal) type of some kind soonish (C# already has one). In the meantime, there are libraries you can use when IEEE-754 binary64 doesn't have the precision you need (such as financial calculations). As to whether it's *misleading*, that's a value judgement I'm not going to comment on other than to say that a ***lot*** of research and thought has gone into the design of these things -- such as that paper I cited above. :-) – T.J. Crowder Feb 14 '22 at 10:11