Skip to content

Учебник: программирование на Java

Бесплатное онлайн обучение программированию на языке Java

Menu
  • Учебник
  • Блог
  • Карта сайта
Menu

Почему в программах Java вместо круглых цифр появляются девятки (9999999999999)?

Posted on 09.01.201809.01.2018 by Java 9

В комментарии к учебному заданию на подсчёт денежных единиц был задан очень интересный вопрос:

Почему 10.03 * 100 = 1002.9999999999999?

Это очень важный вопрос, поскольку если не учитывать погрешности округления, можно столкнуться с трудными для выявления логическими ошибками в работе программы.

Причём погрешности могут возникать сразу в двух местах: при вычислении значения дроби и при конвертации в двоичную систему и обратно.

Давайте посмотрим такой пример:

1/3 + 1/3 + 1/3

Сколько это? Казалось бы, результат будет равен единице.

А если считать в программе?

Дробь 1/3 храниться в виде числа 0.333333333333333 (с конечным количеством цифр после точки).

Итак, если компьютер начнёт складывать 1/3 + 1/3 + 1/3, то он получит:

0.333333333333333 + 0.333333333333333 + 0.333333333333333 будет равно 0.99999999999999, а не единице.

Т.е. из-за того, что компьютер работает с числами, точность которых ограничена, а не с дробями, то теряется точность, возникают ошибки округления.

Если заглянуть ещё глубже, то компьютер понимает числа в двоичной системе счисления, т.е. в виде нулей и единиц. И наша дробь в «мозгах» компьютера переведена в двоичную систему счисления.

Например, число 0.3 (три десятых). У него теряется точность при переводе в двоичную систему счисления и обратно, поскольку для представления 0.3 в двоичной системе требуется много цифр после точки, а количество цифр ограничено.

0.3 в двоичной системе счисления это 0.01001100110011001100110011001100110011001100110011001100110011… (там ещё цифры, которые компьютер отбрасывает).

Теперь если вы конвертируете 0.01001100110011001100110011001100110011001100110011001100110011 в десятичную систему счисления, то вы получите 0.29999999999999999995663191310057982263970188796520233154296875

Т.е. для компьютера даже 1/10 + 2/10 ≠ 3/10

Для вычисления использовался онлайн конвертер:

Appendix D. What Every Computer Scientist Should Know About Floating-Point Arithmetic

2 thoughts on “Почему в программах Java вместо круглых цифр появляются девятки (9999999999999)?”

  1. Семён:
    09.01.2018 в 17:10

    Почему в c++ тот же код выдаёт 1003?

    Ответить
    1. Java 9:
      09.01.2018 в 18:59

      Разные языки, разные наборы правил. Понятно, что в C++ происходит округление. Возможно, дело в применяемом в Java стандарте IEEE 754.

      В других языках программирования я тоже получаю тот результат, который интуитивно ожидаю. Почему в Java по-другому – мне тоже не совсем понятно. Кстати, такой результат мне кажется не совсем правильным. Здесь я описал то, как это явление объясняют преподаватели.

      И ещё по поводу C++, попробуйте поэксперементировать, когда тройка в пятой позиции после запятой – она потеряется. (Если не потеряется, то попробуйте её передвинуть в шестую и седьмую).

      Также если вас интересует тема точности, то интересный эффект даст setprecision(16) – возможно, в какой-то момент вы увидите девятки.

      Ответить

Добавить комментарий Отменить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *

wp-puzzle.com logo




Свежие записи

  • Как установить Java 10 (JDK 10, JRE 10) в Linux
  • Как установить Java 10 (JDK 10, JRE 10) в Windows
  • Почему в программах Java вместо круглых цифр появляются девятки (9999999999999)?
  • Как установить NetBeans 9 для разработки на JDK 9
  • Как установить Java 9 (JDK 9, JRE 9) в Windows

Свежие комментарии

  • м к записи Чтение ввода с консоли
  • Java 9 к записи Чтение ввода с консоли
  • Михаил к записи Чтение ввода с консоли
  • Михаил к записи Упражнения по программированию
  • Михаил к записи Упражнения по программированию

Архивы

  • Июнь 2018
  • Апрель 2018
  • Январь 2018
  • Декабрь 2017
  • Сентябрь 2017
  • Июль 2017
  • Июнь 2017
  • Май 2017




© 2023 Учебник: программирование на Java | Powered by Minimalist Blog WordPress Theme