Не удается получить 0.30000000000000004 путем вычисления

Когда я запускаю консоль 0.1 + 0.2, результат равен 0.30000000000000004. Поэтому я попытался рассчитать его сам. Вот шаги, которые я предпринял.

1) Представьте 0.1 как IEEE754 double:

0.1 = 0 01111111011 1001100110011001100110011001100110011001100110011010

2) Представьте 0.2 как IEEE754 double:

0.2 = 0 01111111100 1001100110011001100110011001100110011001100110011010

Вычисления должны быть корректными здесь, так как я проверил их с помощью моей пользовательской функции, которая показывает, как номер хранится в JavaScript.

3) Преобразуйте оба числа в научную нотацию:

0.1 = 1.1001100110011001100110011001100110011001100110011010 x 2 -4

0.2 = 1.1001100110011001100110011001100110011001100110011010 x 2 -3

Теперь, поскольку число экспонентов отличается от другого, настройте 0.2 на -4:

0.2 = 0.11001100110011001100110011001100110011001100110011010 x 2 -4

4) Добавьте их:

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

Итак, сумма равна:

10.0110011001100110011001100110011001100110011001100111 x 2 -4

5) Нормализовать его:

1.00110011001100110011001100110011001100110011001100111 x 2 -3

6) Разорвите его до 52 бит после точки счисления:

1.1100110011001100110011001100110011001100110011010000 x 2 -3

После удаления экспоненты, я получаю следующее результирующее число:

0.001110011001100110011001100110011001100110011001101 

Когда я конвертирую его в десятичный, используя этот калькулятор, он показывает это:

0.225000000000000088817841970012523233890533447265625

Не точно ожидаемый 0.30000000000000004.

Что мне здесь не хватает?


Попытка # 2: (Исправлена ​​ошибка при настройке экспонентов)

3) Преобразуйте оба числа в научную нотацию:

0.1 = 1.1001100110011001100110011001100110011001100110011010 x 2 -4

0.2 = 1.1001100110011001100110011001100110011001100110011010 x 2 -3

Теперь, поскольку число экспонентов отличается от другого, настройте 0.2 на -4:

0.2 = 11.00110011001100110011001100110011001100110011001101 x 2 -4

4) Добавьте их:

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

Итак, сумма равна:

100.110011001100110011001100110011001100110011001100111 x 2 -4

5) Нормализовать его:

1.00110011001100110011001100110011001100110011001100111 x 2 -2

6) Разобрать его до 52 бит с помощью алгоритма round to the nearest. Ближайшим здесь является усеченное число (округленное):

1.0011001100110011001100110011001100110011001100110011 x 2 -2

После удаления экспоненты, я получаю следующее результирующее число:

0.010011001100110011001100110011001100110011001100110011 

Когда я конвертирую его в десятичный, используя этот калькулятор, он показывает это:

0.299999999999999988897769753748434595763683319091796875

Он почти там на этот раз:), но все еще выключен. Можете ли вы, ребята, помочь мне разобраться с проблемой?

Ответ 1

Чтобы ответить на ваш конкретный вопрос в "Попытке № 2"...

1.00110011001100110011001100110011001100110011001100111 x 2^-2

- 54 бита, бит 54 - '1', второй случай. Вы должны округлить, чтобы сделать значение "ровным", поэтому ответ

1.00110011001100110011001100110011001100110011001101 x 2^-2

который

0.0100110011001100110011001100110011001100110011001101

который

0.3000000000000000444089209850062616169452667236328125

Ответ 2

У вас есть:

0.2 = 1.1001100110011001100110011001100110011001100110011010 x 2 ** -3

Если вы хотите перейти к показателю -4, вам нужно умножить мантиссу на 2, а не разделить его:

0.2 = 10.1001100110011001100110011001100110011001100110011010 x 2 ** -4

Но на самом деле то, что вы хотите, вероятно, 0.1 с показателем -3:

0.1 = 0.1100110011001100110011001100110011001100110011001101(0) x 2 ** -3