Шестнадцатеричный формат с плавающей точкой (теперь называемый HFP компанией IBM ) — формат кодирования чисел с плавающей точкой, впервые представленный на компьютерах IBM System/360 и поддерживаемый на последующих машинах, основанных на этой архитектуре, [1] [2] [3], а также на машинах, которые были предназначены для совместимости приложений с System/360. [4] [5]
По сравнению с плавающей точкой IEEE 754 формат HFP имеет более длинную мантисса и более короткую экспоненту . Все форматы HFP имеют 7 бит экспоненты со смещением 64. Нормализованный диапазон представимых чисел составляет от 16 −65 до 16 63 (приблизительно от 5,39761 × 10 −79 до 7,237005 × 10 75 ).
Число представляется в виде следующей формулы: (−1) знак × 0. мантисса × 16 показатель степени−64 .
Число HFP одинарной точности (которое IBM называет «коротким») хранится в 32-битном слове:
В этом формате начальный бит не подавляется, а точка в шестнадцатеричной системе счисления устанавливается слева от значащей части (дроби в документации IBM и на рисунках).
Поскольку основание равно 16, показатель степени в этой форме примерно в два раза больше эквивалента в IEEE 754; чтобы иметь аналогичный диапазон показателя степени в двоичной системе, потребуется 9 бит показателя степени.
Рассмотрим кодирование значения −118,625 как значения с плавающей запятой одинарной точности HFP.
Значение отрицательное, поэтому знаковый бит равен 1.
Значение 118,625 10 в двоичном виде равно 1110110,101 2 . Это значение нормализуется путем перемещения запятой влево на четыре бита (одну шестнадцатеричную цифру) за раз, пока самая левая цифра не станет нулем, что дает 0,01110110101 2 . Оставшиеся самые правые цифры дополняются нулями, что дает 24-битную дробь .0111 0110 1010 0000 0000 0000 2 .
Нормализованное значение сместило точку основания на две шестнадцатеричные цифры влево, получив множитель и показатель степени 16 +2 . К показателю степени (+2) добавляется смещение +64, что дает +66, что равно 100 0010 2 .
Объединение знака, показателя степени, смещения и нормализованной дроби дает следующую кодировку:
Другими словами, представленное число равно −0,76A000 16 × 16 66 − 64 = −0,4633789… × 16 +2 = −118,625
Представленное число равно +0.FFFFFF 16 × 16 127 − 64 = (1 − 16 −6 ) × 16 63 ≈ +7,2370051 × 10 75
Представленное число равно +0,1 16 × 16 0 − 64 = 16 −1 × 16 −64 ≈ +5,397605 × 10 −79 .
Ноль (0,0) представлен в нормализованной форме как все нулевые биты, что арифметически равно значению +0,0 16 × 16 0 − 64 = +0 × 16 −64 ≈ +0,000000 × 10 −79 = 0. Учитывая дробь всех нулевых битов, любая комбинация положительного или отрицательного знакового бита и ненулевой смещенной экспоненты даст значение, арифметически равное нулю. Однако нормализованная форма, сгенерированная для нуля аппаратным обеспечением ЦП, — это все нулевые биты. Это справедливо для всех трех форматов точности с плавающей точкой. Сложение или вычитание с другими значениями экспоненты может привести к потере точности в результате.
Поскольку основание равно 16, в двоичной мантиссе может быть до трех ведущих нулевых битов. Это означает, что при преобразовании числа в двоичную систему может быть всего 21 бит точности. Из-за эффекта «колебания точности» некоторые вычисления могут быть очень неточными. Это вызвало значительную критику. [6]
Хорошим примером неточности является представление десятичного значения 0,1. Оно не имеет точного двоичного или шестнадцатеричного представления. В шестнадцатеричном формате оно представляется как 0,19999999... 16 или 0,0001 1001 1001 1001 1001 1001 1001... 2 , то есть:
Здесь всего 21 бит, тогда как двоичная версия имеет точность 24 бита.
Шесть шестнадцатеричных цифр точности примерно эквивалентны шести десятичным цифрам (т. е. (6 − 1) log 10 (16) ≈ 6,02). Преобразование шестнадцатеричного числа с плавающей точкой одинарной точности в десятичную строку потребует не менее 9 значащих цифр (т. е. 6 log 10 (16) + 1 ≈ 8,22) для обратного преобразования в то же шестнадцатеричное значение с плавающей точкой.
Формат HFP двойной точности (называемый IBM «длинным») такой же, как и «короткий» формат, за исключением того, что поле дроби шире, а число двойной точности хранится в двойном слове (8 байт):
Экспонента для этого формата охватывает лишь около четверти диапазона соответствующего двоичного формата IEEE.
14 шестнадцатеричных цифр точности примерно эквивалентны 17 десятичным цифрам. Преобразование шестнадцатеричного числа с плавающей точкой двойной точности в десятичную строку потребует не менее 18 значащих цифр для обратного преобразования в то же шестнадцатеричное значение с плавающей точкой.
Названный IBM расширенной точностью, формат HFP с четверной точностью был добавлен в серию System/370 и был доступен на некоторых моделях S/360 (S/360-85, -195 и других по специальному запросу или смоделирован программным обеспечением ОС). Поле дроби расширенной точности шире, а число расширенной точности хранится в виде двух двойных слов (16 байт):
28 шестнадцатеричных цифр точности примерно эквивалентны 32 десятичным цифрам. Преобразование расширенной точности HFP в десятичную строку потребует не менее 35 значащих цифр для обратного преобразования в то же значение HFP. Сохраненная экспонента в младшей части на 14 меньше старшей части, если только она не будет меньше нуля.
Доступные арифметические операции: сложение и вычитание, как нормализованные, так и ненормализованные, и сравнение. Предварительная нормализация выполняется на основе разности экспонент. Умножение и деление предварительно нормализуют ненормализованные значения и усекают результат после одной защитной цифры. Существует операция деления пополам для упрощения деления на два. Начиная с ESA/390, существует операция извлечения квадратного корня. Все операции имеют одну шестнадцатеричную защитную цифру, чтобы избежать потери точности. Большинство арифметических операций усекают как простые карманные калькуляторы. Следовательно, 1 − 16 −8 = 1. В этом случае результат округляется от нуля. [7]
Начиная с S/390 G5 в 1998 году [8] , мэйнфреймы IBM также включали двоичные блоки с плавающей точкой IEEE, которые соответствуют стандарту IEEE 754 для арифметики с плавающей точкой . Десятичные блоки с плавающей точкой IEEE были добавлены в IBM System z9 GA2 [9] в 2007 году с использованием милликода [10] и в 2008 году в IBM System z10 в аппаратном обеспечении. [11]
Современные мэйнфреймы IBM поддерживают три основания с плавающей точкой с 3 шестнадцатеричными (HFP) форматами, 3 двоичными (BFP) форматами и 3 десятичными (DFP) форматами. На ядро приходится два блока с плавающей точкой; один поддерживает HFP и BFP, а другой поддерживает DFP; имеется один файл регистров, FPRs, который содержит все 3 формата. Начиная с z13 в 2015 году, процессоры добавили векторную функцию, которая включает 32 векторных регистра, каждый шириной 128 бит; векторный регистр может содержать два 64-битных или четыре 32-битных числа с плавающей точкой. [12] Традиционные 16 регистров с плавающей точкой накладываются на новые векторные регистры, поэтому некоторые данные можно обрабатывать с помощью традиционных инструкций с плавающей точкой или с помощью более новых векторных инструкций.
Формат IBM HFP используется в:
Поскольку IBM является единственным оставшимся поставщиком оборудования, использующим формат HFP, и поскольку единственные машины IBM, поддерживающие этот формат, — это их мэйнфреймы, немногие форматы файлов требуют его. Исключением является формат файла SAS 5 Transport, который требует FDA; в этом формате «Все числа с плавающей точкой в файле хранятся с использованием представления мэйнфрейма IBM. [...] Большинство платформ используют представление IEEE для чисел с плавающей точкой. [...] Чтобы помочь вам в чтении и/или записи транспортных файлов, мы предоставляем процедуры для преобразования из представления IEEE (как с прямым, так и с обратным порядком байтов) в транспортное представление и обратно». [13] Код для формата IBM также доступен под LGPLv2.1 . [15]
Статья «Архитектура IBM System/360» объясняет этот выбор тем, что «частота предварительного сдвига, переполнения и потери точности после сдвига при сложении с плавающей точкой существенно снижена этим выбором». [16] Это позволило повысить производительность для больших моделей System/360 и снизить стоимость для маленьких. Авторы знали о возможной потере точности, но предполагали, что это не будет иметь существенного значения для 64-битных переменных с плавающей точкой. К сожалению, разработчики, похоже, не знали о законе Бенфорда , который означает, что значительная часть чисел будет страдать от снижения точности.
В книге «Архитектура компьютера» двух архитекторов System/360 цитируется исследование Суини 1958-65 годов, в котором показано, что использование основания больше 2 значительно сокращает количество сдвигов, необходимых для выравнивания и нормализации, в частности, количество различных необходимых сдвигов. Они использовали большее основание, чтобы ускорить реализацию, и выбор основания 16 был естественным, учитывая 8-битные байты. Предполагалось, что 32-битные числа с плавающей точкой будут использоваться только для вычислений, которые не будут распространять ошибки округления, а 64-битная двойная точность будет использоваться для всех научных и инженерных вычислений. Первоначальная реализация двойной точности не имела защитной цифры, чтобы обеспечить правильное округление, но это было изменено вскоре после первых поставок клиентам. [17]