Введение
На этой странице описываются субнормальные числа в общем виде. Подробности о субнормальных и денормализованных числах IEEE см. в разделе IEEE ниже. Денормализованные числа с плавающей точкой вблизи нуля
В информатике субнормальные числа — это подмножество денормализованных чисел (иногда называемых денормалами), которые заполняют область переполнения под нулем в арифметике с плавающей точкой. Любое ненулевое число, модуль которого меньше, чем модуль наименьшего положительного нормального числа, является субнормальным, в то время как денормализованное число может также относиться к числам, выходящим за пределы этого диапазона.
Терминология
В некоторых старых документах (особенно в стандартах, таких как первые версии IEEE 754 и языка C), термин "denormal" используется исключительно для обозначения субнормальных чисел. Это употребление сохраняется в различных документах по стандартам, особенно при описании аппаратного обеспечения, не способного представить какие-либо другие денормализованные числа, однако в данном обсуждении используется термин "субнормальный" в соответствии с редакцией IEEE 754 2008 года. В неформальных обсуждениях термины "субнормальный" и "denormal" часто используются как синонимы, отчасти потому, что за пределами субнормального диапазона не существует денормализованных двоичных чисел IEEE. Термин "число" используется в довольно широком смысле, для описания конкретной последовательности цифр, а не математической абстракции; подробности о связи вещественных чисел с представлениями чисел с плавающей точкой см. в разделе "Числа с плавающей точкой". Для большей ясности вместо "число" может использоваться термин "представление".
Определение
Математические действительные числа могут быть аппроксимированы множеством представлений с плавающей точкой. Одно представление определяется как нормализованное, а другие – как субнормальные, денормализованные или ненормализованные, в зависимости от их соотношения с нормализованным. В нормализованном значении с плавающей точкой в мантиссе (также обычно называемой значащей частью) нет ведущих нулей; вместо этого ведущие нули устраняются путем корректировки экспоненты (например, число 0.0123 будет записано как 1.23 × 10−2). Напротив, денормализованное значение с плавающей точкой имеет мантиссу с ведущей цифрой ноль. Субнормальные числа представляют значения, которые при нормализации имели бы экспоненты меньше минимальной представляемой экспоненты (экспонента имеет ограниченный диапазон). Мантисса (или значащая часть) числа с плавающей точкой IEEE – это часть числа с плавающей точкой, представляющая значащие цифры. Для положительного нормализованного числа она может быть представлена как m0.m1m2m3…mp−2mp−1 (где m представляет значащую цифру, а p – точность) при m0 ≠ 0. Обратите внимание, что для двоичной системы счисления ведущая двоичная цифра всегда равна 1. В субнормальном числе, поскольку экспонента является минимально возможной, ведущей значащей цифрой является ноль (0.m1m2m3…mp−2mp−1), что позволяет представлять числа, более близкие к нулю, чем наименьшее нормализованное число. Число с плавающей точкой можно определить как субнормальное, если его экспонента имеет наименьшее возможное значение. Заполняя промежуток между нормализованными числами, теряются значащие цифры, но не так резко, как при использовании обнуления при переполнении вниз (отбрасывание всех значащих цифр при достижении переполнения вниз). Поэтому получение субнормального числа иногда называют постепенным переполнением вниз, поскольку это позволяет вычислению медленно терять точность при малом результате. В IEEE 754 2008 денормализованные числа были переименованы в субнормальные и поддерживаются как в двоичном, так и в десятичном форматах. В двоичных форматах обмена субнормальные числа кодируются со смещенной экспонентой 0, но интерпретируются как имеющие значение наименьшей допустимой экспоненты, то есть на единицу больше (то есть, как если бы они были закодированы как 1). В десятичных форматах обмена специальное кодирование не требуется, поскольку формат напрямую поддерживает ненормализованные числа. Математически говоря, нормализованные числа с плавающей точкой данного знака примерно логарифмически распределены, и, следовательно, конечное нормализованное число с плавающей точкой не может включать ноль. Субнормальные числа представляют собой линейно распределенный набор значений, заполняющий промежуток между отрицательными и положительными нормализованными числами.
Предыстория
Субнормальные числа гарантируют, что сложение и вычитание чисел с плавающей точкой никогда не приведут к потере значимости; любые два соседних числа с плавающей точкой всегда имеют представимую ненулевую разность. Без постепенной потери значимости, вычитание a − b может привести к появлению нуля, даже если значения не равны. Это, в свою очередь, может вызвать ошибки деления на ноль, которые не возникли бы при использовании постепенной потери значимости. Субнормальные числа были реализованы в Intel 8087 во время разработки стандарта IEEE 754. Они были, пожалуй, самой спорной особенностью в предложении формата KCS, которое в конечном итоге было принято, однако эта реализация показала, что субнормальные числа могут быть поддержаны в практической реализации. Некоторые реализации блоков операций с плавающей точкой не поддерживают субнормальные числа аппаратно, а вместо этого вызывают обработчик для программной поддержки. Хотя это может быть незаметно для пользователя, вычисления, производящие или использующие субнормальные числа, могут выполняться значительно медленнее, чем аналогичные вычисления с нормальными числами.
IEEE
В двоичных форматах чисел с плавающей запятой IEEE субнормальные числа представляются нулевым полем экспоненты и ненулевым полем мантиссы. В двоичных форматах чисел с плавающей запятой IEEE других денормализованных чисел не существует, но они есть в некоторых других форматах, включая форматы чисел с плавающей запятой IEEE десятичной формы.
Проблемы с производительностью
Некоторые системы обрабатывают субнормальные значения аппаратно, так же, как и нормальные значения. Другие оставляют обработку субнормальных значений системному программному обеспечению ("assist"), обрабатывая только нормальные значения и ноль аппаратно. Обработка субнормальных значений программно всегда приводит к значительному снижению производительности. Когда субнормальные значения полностью вычисляются аппаратно, существуют методы реализации, позволяющие обрабатывать их со скоростью, сопоставимой с нормальными числами. Однако скорость вычислений остаётся значительно сниженной на многих современных процессорах x86; в крайних случаях инструкции, включающие субнормальные операнды, могут занимать до 100 дополнительных тактовых циклов, из-за чего самые быстрые инструкции работают в шесть раз медленнее. Эта разница в скорости может представлять угрозу безопасности. Исследователи показали, что она создаёт временной побочный канал, позволяющий злонамеренным веб-сайтам извлекать содержимое страницы с другого сайта внутри веб-браузера. Некоторые приложения нуждаются в коде, предотвращающем появление субнормальных чисел, либо для поддержания точности, либо для избежания снижения производительности на некоторых процессорах. Например, в приложениях обработки звука субнормальные значения обычно представляют сигнал, настолько тихий, что он находится за пределами диапазона человеческого слуха. В связи с этим, распространённой мерой для избежания субнормальных чисел на процессорах, где это приводит к снижению производительности, является обнуление сигнала, как только он достигает субнормального уровня, или добавление чрезвычайно тихого шумового сигнала. Другие методы предотвращения появления субнормальных чисел включают добавление DC-смещения, квантование чисел, добавление сигнала Найквиста и т.д. Начиная с расширения SSE2, Intel предоставляет такую функциональность в аппаратном обеспечении процессора, которое округляет субнормальные числа до нуля.