Типы с плавающей точкой
Общее представление
Тип с плавающей точкой - способ хранения действительных чисел в памяти компьютера с представлением в виде мантиссы и экспоненты, позволяющий покрывать большой диапазон значений с ограниченной точностью.
Числа с плавающей точкой представляют действительные величины в форме, близкой к научной нотации: мантисса умножается на основание в степени экспоненты. В наиболее распространённых реализациях (IEEE 754) основание равно двум, и значение нормализованного числа задаётся формулой .
Такое представление даёт возможность хранить как очень большие, так и очень малые числа при относительно небольшом количестве битов, но при этом точность ограничена количеством битов мантиссы. Понимание структуры представления важно для предсказания погрешностей и поведения при операциях.
Стандарт IEEE 754 и параметры формата
Современные языки и процессоры обычно используют стандарт IEEE 754, который описывает форматы и поведение при операциях. Формат определяется числом бит в знаке, экспоненте и мантиссе. Смещение экспоненты (bias) рассчитывается по формуле .
Параметр точности (p) - количество значащих двоичных цифр (битов) мантиссы плюс скрытый ведущий бит для нормализованных чисел. Для IEEE single (32 бита) и double (64 бита) значения точности различаются: .
Стандарт также задаёт поведение при переполнении, андерфлоу, правила округления и представление специальных значений: ±Inf (бесконечность), NaN (не число), а также поддерживает денормализованные числа для плавного андерфлоу.
Нормализованные и денормализованные числа
Нормализованное число - число, у которого ведущий бит мантиссы равен 1 (в базисе 2): значение вычисляется по общей формуле, где мантисса в диапазоне [1,2). Для нормализованных чисел действует соотношение .
Минимальное положительное нормализованное значение определяется экспонентой, равной минимальному допустимому значению, и выражается как . Когда значение по модулю становится меньше этого порога, в формате появляются денормализованные числа.
Денормализованное (subnormal) число - число, у которого экспонента равна нулю (в битовом поле), и ведущего скрытого единичного бита нет. Его значение задаётся формулой . Самая малая ненулевая величина формата называется ''минимальной денормализованной'' и равна .
Например, представление одного положительного нормального числа в 32-битном формате может выглядеть как . (Схема битов: знак | экспонента | мантисса) {IMAGE_0}
Диапазон, точность и машинный эпсилон
Точность формата характеризуется понятием машинного эпсилона, который даёт порядок относительной погрешности представления. В простом виде машинный эпсилон определяется как и показывает, на сколько приблизительно относительно истинного значения может отличаться ближайший представимый соседный бит числа порядка единицы.
Диапазон представимых значений зависит от числа бит в экспоненте и bias. Верхняя граница приблизительно равна (2-2^{1-p})×2^{e_{max}}, а нижняя для нормальных чисел определяется формулой, приведённой выше. Для чисел с очень малой абсолютной величиной используются денормалы.
Важно помнить, что шаг между соседними представимыми числами зависит от масштаба (порядка): чем больше экспонента, тем больше абсолютный шаг. Это ведёт к потере точности при вычитании близких по величине чисел (катастрофическое сокращение значащих цифр).
Округление и ошибки при вычислениях
IEEE 754 задаёт несколько режимов округления (например, round to nearest even). Округление вводит погрешность, и операции с плавающей точкой чаще всего моделируются через так называемую модель нормального округления: результат операции представим как , где величина δ ограничена машинным эпсилоном ε.
Типичные ошибки включают: накопление погрешности при суммировании большого количества чисел, потерю значащих цифр при вычитании близких по величине чисел, и невозможность точно представить некоторые десятичные дроби в двоичной системе (например, 0.1). Показательный факт: .
Ещё один пример проявления ограниченной точности — арифметические тождества, которые в плавающей точке не выполняются на практике. Так, вычисление суммы и сравнение может дать неожиданный результат: .
Практические примеры преобразований и ошибок
Рассмотрим преобразование десятичного числа в двоичную форму и далее в формат IEEE. Число 12.375_{10} переводится в двоичную запись, и после нормализации получается выражение . На его основе формируется экспонента и мантисса в конкретном формате.
При хранении очень больших чисел мелкие добавления могут полностью теряться. Например, при вычислении выражения маленькая единица теряется из-за масштабного различия — результат может быть равен нулю после выполнения всех шагов из-за округления.
Практика показывает: при проектировании численных алгоритмов нужно учитывать порядок операций, использовать корректирующие приёмы (Kahan summation и т.п.), а также проверять результаты с учётом относительной и абсолютной погрешности, задаваемой машинным эпсилон.
Рекомендации для программиста
1) Не сравнивайте числа с плавающей точкой на строгую равенство; вместо этого используйте сравнение с допустимой погрешностью, зависящей от величины чисел и от машинного эпсилона. 2) При суммировании большого количества чисел рассмотрите перестановку по модулю или использование компенсирующих алгоритмов.
3) При необходимости высокой точности используйте форматы с большей мантиссой (double, long double) или библиотеки произвольной точности. 4) Будьте внимательны при преобразованиях из десятичной в двоичную систему и обратно: не все десятичные дроби представимы точно в двоичной форме, что приводит к аккумулируемым ошибкам.
Ключевые идеи: знать структуру формата (знак, экспонента, мантисса), понимать роль bias и p, оценивать машинный эпсилон и предвидеть ситуации потери значащих цифр — это позволит писать более надёжный и стабильный код при работе с вещественными числами.