Расширенная точность относится к форматам чисел с плавающей точкой , которые обеспечивают большую точность, чем базовые форматы с плавающей точкой. [1] Расширенные форматы точности поддерживают базовый формат, минимизируя ошибки округления и переполнения в промежуточных значениях выражений в базовом формате. В отличие от расширенной точности , арифметика произвольной точности относится к реализациям гораздо больших числовых типов (с объемом памяти, который обычно не является степенью двойки) с использованием специального программного обеспечения (или, реже, оборудования).
Существует долгая история расширенных форматов с плавающей точкой, уходящая корнями почти в середину прошлого века [ когда? ] . Различные производители использовали различные форматы для расширенной точности для разных машин. Во многих случаях формат расширенной точности не совсем то же самое, что масштабирование обычных форматов одинарной и двойной точности, которые он призван расширять. В некоторых случаях реализация была просто программным изменением формата данных с плавающей точкой, но в большинстве случаев расширенная точность была реализована аппаратно, либо встроена в сам центральный процессор , либо, что чаще, встроена в аппаратное обеспечение дополнительного, присоединенного процессора, называемого «блоком с плавающей точкой » (FPU) или «процессором с плавающей точкой» ( FPP ), доступным для ЦП как быстрое устройство ввода/вывода.
IBM 1130 , проданный в 1965 году, [2] предлагал два формата с плавающей точкой: 32-битный формат «стандартной точности» и 40-битный формат «расширенной точности». Формат стандартной точности содержит 24-битную мантиссу с дополнением до двух , в то время как расширенная точность использует 32-битную мантиссу с дополнением до двух. Последний формат полностью использует 32-битные целочисленные операции ЦП. Характерной чертой обоих форматов является 8-битное поле, содержащее степень двойки, смещенную на 128. Арифметические операции с плавающей точкой выполняются программным обеспечением, а двойная точность вообще не поддерживается. Расширенный формат занимает три 16-битных слова, а дополнительное пространство просто игнорируется. [3]
IBM System/360 поддерживает 32-битный «короткий» формат с плавающей точкой и 64-битный «длинный» формат с плавающей точкой. [4] 360/85 и последующая System/370 добавляют поддержку 128-битного «расширенного» формата. [5] Эти форматы по-прежнему поддерживаются в текущем дизайне , где они теперь называются форматами « шестнадцатеричного числа с плавающей точкой » (HFP).
Порт Microsoft BASIC для процессора 6502 , например, в таких адаптациях, как Commodore BASIC , AppleSoft BASIC , KIM-1 BASIC или MicroTAN BASIC, поддерживает расширенный 40-битный вариант формата с плавающей точкой Microsoft Binary Format (MBF) с 1977 года. [6]
Стандарт IEEE 754 с плавающей точкой рекомендует, чтобы реализации предоставляли расширенные форматы точности. Стандарт определяет минимальные требования для расширенного формата, но не определяет кодировку. [7] Кодировка выбирается разработчиком. [8]
Процессоры IA32 , x86-64 и Itanium поддерживают, безусловно, наиболее влиятельный формат в этом стандарте — 80-битный (64-битная мантисса) «двойной расширенный» формат Intel, описанный в следующем разделе .
Математические сопроцессоры Motorola 6888x и процессоры Motorola 68040 и 68060 также поддерживают 64-битный значимый формат расширенной точности (похожий на формат Intel, хотя дополненный до 96-битного формата с 16 неиспользуемыми битами, вставленными между полями экспоненты и значимыми, а значения с экспонентой ноль и битом 63 единица являются нормализованными значениями [9] ). Последующие процессоры Coldfire не поддерживают этот 96-битный расширенный формат точности. [10]
Математический сопроцессор FPA10 для ранних процессоров ARM также поддерживает 64-битный значащий формат расширенной точности (похожий на формат Intel, хотя и дополненный до 96-битного формата с 16 нулевыми битами, вставленными между полями знака и экспоненты), но без правильного округления. [11]
80-битные форматы x87 и Motorola 68881 соответствуют требованиям двойного расширенного формата IEEE 754-1985 [12] , как и 128-битный двоичный формат IEEE 754 .
Формат расширенной точности x86 — это 80-битный формат, впервые реализованный в математическом сопроцессоре Intel 8087 и поддерживаемый всеми процессорами на базе архитектуры x86 , включающими блок вычислений с плавающей запятой (FPU).
Intel 8087 был первым устройством x86 , которое поддерживало арифметику с плавающей точкой на аппаратном уровне. Он был разработан для поддержки 32-битного формата «одинарной точности» и 64-битного формата «двойной точности» для кодирования и обмена числами с плавающей точкой. Расширенный формат был разработан не для хранения данных с более высокой точностью, а для обеспечения более надежного и точного вычисления временных двойных результатов за счет минимизации ошибок переполнения и округления в промежуточных вычислениях. [a] [14] [15] Все регистры с плавающей точкой в 8087 поддерживают этот формат, и он автоматически преобразует числа в этот формат при загрузке регистров из памяти , а также преобразует результаты обратно в более традиционные форматы при сохранении регистров обратно в память. Чтобы обеспечить сохранение промежуточных результатов подвыражений в переменных повышенной точности и их продолжение в операторах языка программирования, а также возобновление прерванных вычислений с того места, на котором они были прерваны, предусмотрены инструкции , которые передают значения между этими внутренними регистрами и памятью без выполнения каких-либо преобразований, что, таким образом, обеспечивает доступ к расширенному формату вычислений [b] , что также возрождает вопрос о точности функций таких чисел, но с более высокой точностью.
Блоки с плавающей точкой (FPU) на всех последующих процессорах x86 поддерживали этот формат. В результате можно разработать программное обеспечение, которое использует преимущества более высокой точности, предоставляемой этим форматом. Уильям Кахан , главный разработчик арифметики x87 и первоначального предложения стандарта IEEE 754, отмечает о разработке плавающей точки x87: «Расширенный формат, настолько широкий, насколько мы осмелились (80 бит), был включен для выполнения той же вспомогательной роли, которую 13-десятичный внутренний формат выполняет в 10-десятичных калькуляторах Hewlett-Packard». [17] Более того, Кахан отмечает, что 64 бита были самой широкой значащей, через которую можно было выполнять распространение переноса без увеличения времени цикла на 8087, [18] и что расширенная точность x87 была разработана для расширения до более высокой точности в будущих процессорах:
Этот 80-битный формат использует один бит для знака мантиссы, 15 бит для поля экспоненты (т. е. тот же диапазон, что и 128-битный формат четверной точности IEEE 754 ) и 64 бита для мантиссы. Поле экспоненты смещено на 16383, что означает , что 16383 должно быть вычтено из значения в поле экспоненты для вычисления фактической степени 2. [20] Значение поля экспоненты 32767 (все пятнадцать бит 1 ) зарезервировано для того, чтобы включить представление специальных состояний, таких как бесконечность и Not a Number . Если поле экспоненты равно нулю, значение является ненормальным числом, а экспонента 2 равна −16382. [21]
В следующей таблице « s » — значение знакового бита (0 означает положительное, 1 означает отрицательное), « e » — значение поля экспоненты, интерпретируемое как положительное целое число, а « m » — мантисса, интерпретируемая как положительное двоичное число, где двоичная точка расположена между битами 63 и 62. Поле « m » представляет собой комбинацию целой и дробной частей в приведенной выше диаграмме.
В отличие от форматов одинарной и двойной точности , этот формат не использует неявный / скрытый бит . Вместо этого бит 63 содержит целую часть мантиссы, а биты 62–0 содержат дробную часть. Бит 63 будет равен 1 для всех нормализованных чисел. При разработке 8087 у этой конструкции было несколько преимуществ :
80-битный формат с плавающей точкой был широко доступен к 1984 году [25] после разработки C, Fortran и подобных компьютерных языков, которые изначально предлагали только общие 32- и 64-битные размеры с плавающей точкой. В конструкции x86 большинство компиляторов C теперь поддерживают 80-битную расширенную точность через тип long double , и это было указано в стандартах C99 / C11 (арифметика с плавающей точкой IEC 60559 (Приложение F)). Компиляторы на x86 для других языков часто также поддерживают расширенную точность, иногда через нестандартные расширения: например, Turbo Pascal предлагает extended
тип , а несколько компиляторов Fortran имеют REAL*10
тип (аналогичный REAL*4
и ). Такие компиляторы также обычно включают математические подпрограммыREAL*8
с расширенной точностью , такие как квадратный корень и тригонометрические функции , в свои стандартные библиотеки .
80-битный формат с плавающей точкой имеет диапазон (включая субнормальные значения ) приблизительно от 3,65 × 10−4951 до 1,18 × 10+4932 .Хотя log 10 ( 2 64 ) ≈ 19,266 ,этот формат обычно описывается как дающий приблизительно восемнадцать значащих цифр точности (пол log 10 ( 2 63 ) ,минимальная гарантированная точность). Использование десятичной дроби при обсуждении двоичной системы неудачно, поскольку большинство десятичных дробей представляют собой повторяющиеся последовательности в двоичной системе, как и 2/3 в десятичной системе счисления. Таким образом, значение, такое как 10,15, представляется в двоичной системе счисления как эквивалентное 10,1499996185 и т. д. в десятичной системе счисления для ,REAL*4
но 10,150000000000000035527 и т. д. вREAL*8
: взаимное преобразование будет включать приближение, за исключением тех немногих десятичных дробей, которые представляют точное двоичное значение, например 0,625 . ДляREAL*10
десятичная строка будет 10,1499999999999999996530553 и т. д. Последняя 9 цифр является восемнадцатой дробной цифрой и, таким образом, двадцатой значащей цифрой строки. Границы преобразования между десятичным и двоичным форматом для 80-битного формата можно задать следующим образом: если десятичная строка с не более чем 18 значащими цифрами правильно округлена до 80-битного двоичного значения с плавающей точкой IEEE 754 (как на входе), а затем преобразована обратно в то же количество значащих десятичных цифр (как на выходе), то конечная строка будет точно соответствовать оригиналу; в то время как, наоборот, если 80-битное двоичное значение с плавающей точкой IEEE 754 правильно преобразовано и (ближайшее) округлено до десятичной строки с не менее чем 21 значащей десятичной цифрой, а затем преобразовано обратно в двоичный формат, то оно будет точно соответствовать оригиналу. [12] Эти приближения особенно проблематичны при указании наилучшего значения для констант в формулах с высокой точностью, которое может быть вычислено с помощью арифметики произвольной точности .
Ярким примером необходимости минимальной точности в 64 бита в мантиссе формата расширенной точности является необходимость избежать потери точности при выполнении возведения в степень значений двойной точности . [26] [27] [28] [c] Устройства с плавающей точкой x86 не предоставляют инструкцию, которая напрямую выполняет возведение в степень : вместо этого они предоставляют набор инструкций, которые программа может использовать последовательно для выполнения возведения в степень с использованием уравнения:
Чтобы избежать потери точности, промежуточные результаты " log 2 ( x ) " и " y · log 2 ( x ) " должны быть вычислены с гораздо более высокой точностью, поскольку фактически и поле экспоненты, и поле мантиссы x должны вписываться в поле мантиссы промежуточного результата. Впоследствии поле мантиссы промежуточного результата разделяется между полями экспоненты и мантиссы конечного результата, когда вычисляется 2 промежуточных результата . Ниже это требование описывается более подробно.
После небольшой распаковки значение двойной точности IEEE 754 можно представить следующим образом:
где s — знак экспоненты (0 или 1), E — несмещенная экспонента, которая является целым числом в диапазоне от 0 до 1023, а M — мантисса, которая является 53-битным значением, попадающим в диапазон 1 ≤ M < 2. Отрицательные числа и ноль можно игнорировать, поскольку логарифм этих значений не определен. Для целей этого обсуждения M не имеет 53 бит точности, поскольку он ограничен быть больше или равен единице, т. е. скрытый бит не учитывается в точности (обратите внимание, что в ситуациях, когда M меньше 1, значение фактически является ненормальным и, следовательно, уже могло понести потерю точности. Эта ситуация выходит за рамки этой статьи).
Взяв логарифм этого представления числа двойной точности и упростив, получаем следующее:
Этот результат показывает, что при взятии логарифма по основанию 2 знак показателя степени исходного значения становится знаком логарифма, показатель степени исходного значения становится целой частью мантиссы логарифма, а мантисса исходного значения преобразуется в дробную часть мантиссы логарифма.
Поскольку E — целое число в диапазоне от 0 до 1023, для представления целой части логарифма требуется до 10 бит слева от запятой основания. Поскольку M попадает в диапазон 1 ≤ M < 2 , значение log 2 M будет попадать в диапазон 0 ≤ log 2 M < 1, поэтому для представления дробной части логарифма требуется не менее 52 бит справа от запятой основания. Объединение 10 бит слева от запятой основания с 52 битами справа от запятой основания означает, что значимая часть логарифма должна быть вычислена с точностью не менее 62 бит. На практике значения M , меньшие, требуют 53 бита справа от запятой основания, а значения M , меньшие, требуют 54 бита справа от запятой основания, чтобы избежать потери точности. Сбалансировав это требование для дополнительной точности справа от запятой, показатели степени менее 512 требуют всего 9 бит слева от запятой, а показатели степени менее 256 требуют всего 8 бит слева от запятой.
Заключительная часть расчета возведения в степень — вычисление 2 промежуточных результатов . «Промежуточный результат» состоит из целой части « I », добавленной к дробной части « F ». Если промежуточный результат отрицательный, то необходима небольшая корректировка, чтобы получить положительную дробную часть, поскольку и « I », и « F » являются отрицательными числами.
Для положительных промежуточных результатов:
Для отрицательных промежуточных результатов:
Таким образом, целая часть промежуточного результата (" I " или " I − 1 ") плюс смещение становятся показателем степени конечного результата, а преобразованная положительная дробная часть промежуточного результата: 2 F или 2 F + 1 становится мантиссом конечного результата. Чтобы обеспечить точность 52 бита для конечного результата, положительная дробная часть должна поддерживаться как минимум в 52 бита.
В заключение следует отметить, что точное количество бит точности, необходимое в мантиссе промежуточного результата, в некоторой степени зависит от данных, но 64 бит достаточно, чтобы избежать потери точности в подавляющем большинстве вычислений возведения в степень с использованием чисел двойной точности .
Число бит, необходимое для экспоненты формата расширенной точности, следует из требования, чтобы произведение двух чисел двойной точности не переполнялось при вычислении с использованием расширенного формата. Наибольшая возможная экспонента значения двойной точности равна 1023, поэтому экспонента наибольшего возможного произведения двух чисел двойной точности равна 2047 (11-битное значение). Добавление смещения для учета отрицательных экспонент означает, что поле экспоненты должно быть шириной не менее 12 бит.
Объединение этих требований: 1 бит для знака, 12 бит для смещенной экспоненты и 64 бита для мантиссы означает, что для формата расширенной точности потребуется не менее 77 бит. Инженерные соображения привели к окончательному определению 80-битного формата (в частности, стандарт IEEE 754 требует, чтобы диапазон экспоненты формата расширенной точности соответствовал диапазону следующего по величине, четверного , формата точности, который составляет 15 бит). [27]
Другим примером вычислений, которые выигрывают от арифметики повышенной точности, являются итерационные схемы уточнения , используемые для косвенного устранения ошибок, накопленных в прямом решении во время, как правило, очень большого количества вычислений, выполняемых для числовой линейной алгебры. [30]
long double
использование 80-битных чисел с плавающей точкой на системах x86. Однако это поведение, определяемое реализацией, и не является обязательным, но допускается стандартом, как указано для оборудования IEEE 754 в стандарте C99 «Приложение F Арифметика с плавающей точкой IEC 60559». GCC также предоставляет типы __float80
и __float128
. [31]long-float
использование 80-битных чисел с плавающей точкой на системах x86.real
использование наибольшего размера плавающей точки, реализованного в оборудовании, например 80 бит для процессоров x86 . На других машинах это будет самый широкий тип плавающей точки, изначально поддерживаемый процессором, или 64 бит двойной точности, в зависимости от того, что шире.extended
80-битный тип, доступный в дополнение к real
/ single
(32 бита) и double
(64 бита), либо изначально (при наличии сопроцессора 80x87), либо эмулируемый (через библиотеку Turbo87); этот extended
тип доступен на 16-, 32- и 64-битных платформах, возможно, с дополнением . [32]Float80
тип данных.EXT
байтовый EXTENDED
тип данных с плавающей точкой расширенной точности.