"Информатика (базовый и углублённый уровни) (в 2 частях)", Поляков К.Ю., Еремин Е.А.
Вещественные числа нужны программам для вычислений с измерениями, дробями и величинами разных масштабов. Но память компьютера ограничена, поэтому такие числа обычно хранятся не точно, а приближённо — в формате с плавающей точкой. Из-за округления результат сложения или другого действия может отличаться от математически точного. Чтобы программы работали надёжно, нужно учитывать точность хранения, осторожно выбирать порядок вычислений и сравнивать числа с допустимой погрешностью.
Текст подготовлен нейронной сетью по теме параграфа и не заменяет учебник — важные факты и формулировки сверяйте с ним.
Вещественное число в компьютере — число, которое обычно хранится приближённо в формате с плавающей точкой. Это относится и к многим дробям, и к очень большим или малым значениям. Понимание приближённости помогает не ожидать от вычислений абсолютной точности.
Представление с плавающей точкой — запись числа через знак, мантиссу и порядок, при которой положение запятой не фиксировано. Например, одно и то же значение можно записать в виде 3,14 × 10² или 0,314 × 10³. Такой формат нужен, чтобы хранить числа с разным масштабом.
Мантисса — значащая часть числа, задающая его цифры с ограниченной точностью. Чем больше разрядов отведено под мантиссу, тем подробнее можно записать значение. Именно мантисса определяет, насколько близко хранимое число к исходному.
Машинное эпсилон — наименьшее положительное число ε, для которого в данной арифметике выражение 1 + ε отличается от 1. Оно показывает, насколько мелкие изменения числа около единицы ещё различимы для компьютера. Эпсилон помогает оценивать точность вычислений, но не заменяет выбор допуска для конкретной задачи.
Память компьютера может хранить только конечное количество разрядов. Между тем вещественных чисел бесконечно много, даже если ограничить их небольшим промежутком. Поэтому каждому числу нельзя выделить отдельную точную комбинацию разрядов: часть значений приходится заменять ближайшими представимыми числами. Так возникает приближение уже при сохранении данных.
Плавающая точка позволяет использовать разряды эффективно: мантисса хранит значащие цифры, а порядок задаёт масштаб. Благодаря этому можно представлять как очень малые, так и очень большие значения, не записывая длинные цепочки нулей. Однако число разрядов мантиссы конечно, поэтому точность зависит от того, сколько значащих цифр удаётся сохранить. Увеличение или уменьшение порядка меняет масштаб, но не добавляет мантиссе новых цифр.
Компьютер выполняет вычисления в двоичной системе, а не в десятичной. Некоторые конечные десятичные дроби в двоичной записи становятся бесконечными, подобно тому как ⅓ не имеет конечной десятичной записи. Хранение такой дроби требует остановиться после ограниченного числа разрядов и округлить значение. Поэтому числа 0,1 и 0,2 обычно представлены лишь приближённо.
Округление может появиться не только при записи исходного числа, но и после арифметической операции. Точный математический результат иногда содержит больше цифр, чем помещается в мантиссу, поэтому компьютер сохраняет ближайшее доступное значение. Если исходные значения уже были приближёнными, новое действие использует эти приближения и может добавить свою погрешность. В итоге полученное машинное число не обязательно совпадает с точным ответом.
Порядок вычислений важен, потому что округляются промежуточные результаты. При сложении чисел сильно различающихся величин малое слагаемое может не поместиться в значащие разряды суммы и фактически потеряться. Перегруппировка действий меняет промежуточные значения, а значит, и то, какие цифры будут отброшены при округлении. Поэтому математически равные выражения в программе иногда дают разные машинные результаты.
| Операция или ситуация | Что происходит | На что обратить внимание |
|---|---|---|
| Хранение числа | Значение округляется до ближайшего представимого. | Конечная десятичная дробь может иметь бесконечную двоичную запись. |
| Сложение и вычитание | Результат может округлиться; малые разряды иногда теряются. | Особенно внимательно проверяйте действия с числами разных масштабов. |
| Умножение и деление | Точный результат часто нельзя полностью уместить в мантиссе. | Учитывайте погрешность и возможность выхода за диапазон типа. |
| Сравнение вещественных чисел | Приближённые значения могут чуть различаться. | Для близости используйте допуск, а не только точное равенство. |
| Накопление ошибки округления | Повторные операции могут увеличивать отличие от точного результата. | Проверяйте порядок вычислений и точность, достаточную для задачи. |
Таблица помогает определить, где в вычислении вероятнее всего появится погрешность. Перед сравнением результатов выберите допуск, подходящий по масштабу и точности задачи. Если действие повторяется много раз, оцените, как ошибки промежуточных округлений могут повлиять на итог.
Условие. Вычислить в программе 0.1 + 0.2 и сравнить результат с 0.3. Нужно выяснить, почему проверка на точное равенство может не сработать. Рассмотрим, что происходит на каждом этапе.
Ответ. Сумма может оказаться не равной 0.3 при точном сравнении из-за округления. Для проверки близости используют условие |(0.1 + 0.2) − 0.3| < ε.
Условие. Сравнить результаты выражений (1e16 + 1) − 1 и (1e16 − 1e16) + 1. Запись 1e16 означает 1 × 10¹⁶. Математически оба выражения равны 1, но вычисления выполняются с ограниченной точностью.
Ответ. В типичном формате с плавающей точкой результаты могут быть разными: первое выражение даст 0, второе — 1. Порядок операций влияет на то, какие разряды сохраняются.
Условие. Написать программу, которая проверяет, близки ли вещественные числа a и b с заданной точностью ε. Точное условие a == b для округлённых значений ненадёжно. Построим проверку через разность.
Ответ. Числа считают близкими, когда |a − b| < ε. Значение ε выбирают по масштабу чисел и требованиям задачи, а не произвольно.
Считать, что любая конечная десятичная дробь хранится точно, — ошибка: её двоичная запись может быть бесконечной. Так думают, потому что в привычной десятичной записи дробь выглядит завершённой. Проверьте себя, переводя дробь в двоичную систему или сравнивая её с известными точно представимыми значениями.
Проверка результата на точное равенство часто ненадёжна, поскольку округление способно изменить последние разряды. Условие a == b кажется естественным после обычных вычислений с числами. Для проверки близости оцените модуль разности и сравните его с заранее выбранным допуском.
Перестановка или перегруппировка операций не всегда сохраняет результат программы. Ошибочно полагать, что свойства точной арифметики полностью действуют и для округляемых промежуточных значений. Проверьте выражение несколькими порядками вычислений, особенно если в нём есть очень большие и малые числа.
Увеличение числа знаков после запятой при выводе не повышает точность вычислений. Дополнительные цифры могут лишь показывать уже имеющееся приближённое значение подробнее. Чтобы проверить точность, уточните формат хранения и исследуйте погрешность, а не только настройки вывода.
Для понимания плавающей точки полезно знать позиционные системы счисления и двоичную запись чисел: именно особенности двоичного представления объясняют округление десятичных дробей. Тема нужна при программировании численных методов, моделировании физических процессов и обработке измерений, где значения часто приблизительны изначально. При анализе алгоритмов понимание погрешности помогает оценить надёжность вычислений и выбрать подходящий тип данных.
Почему 0.1 + 0.2 в программе может быть не равно 0.3?
Двоичная запись дробей 0,1 и 0,2 бесконечна, поэтому компьютер хранит их приближённо. При сложении возникает ещё одно округление, и результат может немного отличаться от 0,3.
Что означает запись числа с плавающей точкой?
Число задаётся знаком, мантиссой и порядком, который определяет масштаб числа. Запятая как бы перемещается в зависимости от порядка, поэтому можно хранить очень большие и очень малые числа.
Можно ли хранить вещественные числа абсолютно точно?
В обычном формате с плавающей точкой нельзя точно хранить все вещественные числа: разрядов памяти конечное число, а таких чисел бесконечно много. Некоторые значения, например целые числа в допустимом диапазоне, представляются точно, но многие дроби — лишь приближённо.
Как правильно сравнивать два вещественных числа?
Обычно сравнивают модуль их разности с выбранным допуском ε: числа считают близкими, если |a − b| < ε. Допуск выбирают с учётом масштаба величин и требуемой точности задачи.
Почему перестановка операций иногда меняет результат?
После каждой операции промежуточный результат может округляться. Если порядок действий изменить, изменятся промежуточные значения и округления, поэтому итог может отличаться.
§ 30. Операции с вещественными числами