14

When I run in the console 0.1 + 0.2 the result is 0.30000000000000004. So I tried to calculate it myself. Here are the steps I've taken.

1) Represent 0.1 as IEEE754 double:

0.1 = 0 01111111011 1001100110011001100110011001100110011001100110011010

2) Represent 0.2 as IEEE754 double:

0.2 = 0 01111111100 1001100110011001100110011001100110011001100110011010

The calculations should be correct here since I've checked them using my custom function that shows how the number is stored by JavaScript.

3) Convert both numbers to scientific notation:

0.1 = 1.1001100110011001100110011001100110011001100110011010 x 2-4

0.2 = 1.1001100110011001100110011001100110011001100110011010 x 2-3

Now since exponent number is different, let's adjust the 0.2 to have -4:

0.2 = 0.11001100110011001100110011001100110011001100110011010 x 2-4

4) Add them:

  1.1001100110011001100110011001100110011001100110011010
+ 0.1100110011001100110011001100110011001100110011001101
  ------------------------------------------------------
 10.0110011001100110011001100110011001100110011001100111

So the sum is:

10.0110011001100110011001100110011001100110011001100111 x 2-4

5) Normalize it:

1.00110011001100110011001100110011001100110011001100111 x 2-3

6) Round it up to 52 bits after radix point:

1.1100110011001100110011001100110011001100110011010000 x 2-3

After I remove the exponent, then I end up with the following resulting number:

0.001110011001100110011001100110011001100110011001101 

When I convert it to decimal using this calculator it shows this:

0.225000000000000088817841970012523233890533447265625

Not exactly the expected 0.30000000000000004.

What am I missing here?


Attempt #2: (Fixed error when adjusting exponents)

3) Convert both numbers to scientific notation:

0.1 = 1.1001100110011001100110011001100110011001100110011010 x 2-4

0.2 = 1.1001100110011001100110011001100110011001100110011010 x 2-3

Now since exponent number is different, let's adjust the 0.2 to have -4:

0.2 = 11.00110011001100110011001100110011001100110011001101 x 2-4

4) Add them:

      1.1001100110011001100110011001100110011001100110011010
   + 11.0011001100110011001100110011001100110011001100110100
      ------------------------------------------------------
    100.110011001100110011001100110011001100110011001100111

So the sum is:

100.110011001100110011001100110011001100110011001100111 x 2-4

5) Normalize it:

1.00110011001100110011001100110011001100110011001100111 x 2-2

6) Round it to 52 bits using round to the nearest algorithm. The nearest here is the truncated number (rounded down):

1.0011001100110011001100110011001100110011001100110011 x 2-2

After I remove the exponent, then I end up with the following resulting number:

0.010011001100110011001100110011001100110011001100110011 

When I convert it to decimal using this calculator it shows this:

0.299999999999999988897769753748434595763683319091796875

It's almost there this time :), but is still off. Can you guys please help me figure out the problem?

Community
  • 1
  • 1
Max Koretskyi
  • 101,079
  • 60
  • 333
  • 488
  • 1
    There must be a grave mistake somewhere, as `0.2250000` is not even close to the correct value of `0.30000000000000000000....` – Jacob Krall May 19 '16 at 15:16
  • @Bergi, yes, I used the converted I linked to. – Max Koretskyi May 19 '16 at 15:19
  • 1 * 2**-3 = 10 * 2**-4 and you produced 0.1 * 2**-4 – Alex Kudryashev May 19 '16 at 15:35
  • Are you certain you rounded correctly? The binary numbers before and after the rounding are completely different. Your number at ***5*** is correct, afterwards it is not. – Spencer Wieczorek May 19 '16 at 15:37
  • 1
    @SpencerWieczorek, can you please specify what the correctly rounded number should be? – Max Koretskyi May 19 '16 at 15:42
  • @Maximus Depends how you are rounding. Are you rounding up for a larger number to the right of the radix point? Why not round to the closest number from the original 53 bits? Just the different of the first few bits are largely different numbers: `1.0011..` to `1.1100..` is a huge difference. – Spencer Wieczorek May 19 '16 at 16:00
  • I'm rounding to the nearest. As I calculated the nearest tends to be original plus one (round up). Are you saying the nearest is the number rounded down (truncated) ? – Max Koretskyi May 19 '16 at 19:51
  • @JacobKrall, after I corrected some mistakes, it's much closer to the expected value now, I got `0.299999999999999988897769753748434595763683319091796875`. But it's still off. Can you see where the problem is? – Max Koretskyi May 20 '16 at 06:07
  • @SpencerWieczorek,after I corrected some mistakes, it's much closer to the expected value now, I got `0.299999999999999988897769753748434595763683319091796875`. But it's still off. Can you see where the problem is? – Max Koretskyi May 20 '16 at 06:08
  • You are not rounding correctly. First of all, rounding is to 53 bits, not 52. And "ties to even" will make you round up. – Rick Regan May 20 '16 at 14:19
  • @RickRegan, can you please show me the correct rounding in a separate answer? – Max Koretskyi May 20 '16 at 14:24
  • I can do that...but I do have an unaccepted answer to your question at http://stackoverflow.com/questions/37111324/how-do-i-round-this-binary-number-to-the-nearest-even/ ... did that not help? – Rick Regan May 20 '16 at 14:37
  • @RickRegan, I accepted the one you linked to. I could've missed it. Thanks for your answer here, I'll check it and get back to you with questions) – Max Koretskyi May 20 '16 at 15:06

2 Answers2

3

You have:

0.2 = 1.1001100110011001100110011001100110011001100110011010 x 2 ** -3

If you want to get to exponent -4, you need to multiply the mantissa by 2, not divide it:

0.2 = 10.1001100110011001100110011001100110011001100110011010 x 2 ** -4

But actually what you want is probably 0.1 with a -3 exponent:

0.1 = 0.1100110011001100110011001100110011001100110011001101(0) x 2 ** -3
Holt
  • 36,600
  • 7
  • 92
  • 139
  • ah, yeah, this could be the problem. Let me recalculate and see what that turns out to be – Max Koretskyi May 19 '16 at 15:21
  • _But actually what you want is probably 0.1 with a -3 exponent_ - why? – Max Koretskyi May 19 '16 at 15:27
  • 1
    @Maximus Because that is how IEEE754 is specified, you need to align both numbers by shifting bits in the mantissa of the number with the smallest exponent, see https://cseweb.ucsd.edu/classes/wi13/cse140-a/IEEE754.pdf. – Holt May 19 '16 at 15:32
  • I see, thanks. Let me recalculate using your input and I'll get back – Max Koretskyi May 19 '16 at 15:35
  • How did you come up with the number `0.2 = 10.1001100110011001100110011001100110011001100110011010 x 2 ** -4`? When the original number `1.1001100110011001100110011001100110011001100110011010` multiplied by 2, the resulting number is `11.00110011001100110011001100110011001100110011001101` – Max Koretskyi May 20 '16 at 05:36
  • I just recalculated, can you please take a look at the `attempt #2` section in my question? – Max Koretskyi May 20 '16 at 06:06
2

To answer your specific question in your "Attempt #2"...

1.00110011001100110011001100110011001100110011001100111 x 2^-2

is 54 bits, with bit 54 being '1', a halfway case. You have to round up to make the significand "even", so the answer is

1.00110011001100110011001100110011001100110011001101 x 2^-2

which is

0.0100110011001100110011001100110011001100110011001101

which is

0.3000000000000000444089209850062616169452667236328125
Kokizzu
  • 24,974
  • 37
  • 137
  • 233
Rick Regan
  • 3,407
  • 22
  • 28
  • Thanks, that's exactly the resulting number I'm after :). Can you please show me in your answer how to do rounding using comparing? I mean show two possible numbers: `round down` and `round up` and then show the difference between them and the original number. This would greatly help me understand rounding. – Max Koretskyi May 20 '16 at 15:33
  • It sounds like you're asking a new question (and I don't know what the question is). – Rick Regan May 20 '16 at 15:48