Формат двойной точности с плавающей запятой
Формат чисел с плавающей запятой двойной точности (иногда называемый FP64 или float64 ) — это с плавающей запятой формат чисел , обычно занимающий 64 бита в памяти компьютера; он представляет широкий динамический диапазон числовых значений с использованием плавающей точки счисления .
Двойную точность можно выбрать, когда диапазон или точность одинарной точности недостаточны.
В IEEE 754 стандарте битный формат base-2 официально называетсяbinary64 64 - ; он был назван двойным в IEEE 754-1985 . по основанию 2 IEEE 754 определяет дополнительные форматы с плавающей запятой, включая 32-битные представления одинарной точности и, в последнее время, представления по основанию 10 ( десятичная с плавающей запятой ).
Одним из первых языков программирования , предоставивших типы данных с плавающей запятой, был Фортран . [ нужна ссылка ] До широкого распространения стандарта IEEE 754-1985 представление и свойства типов данных с плавающей запятой зависели от производителя компьютера и модели компьютера, а также от решений, принятых разработчиками языка программирования. Например, GW-BASIC тип данных двойной точности представлял собой 64-битный формат с плавающей запятой MBF.
с плавающей запятой Форматы |
---|
ИЭЭЭ 754 |
|
Другой |
Альтернативы |
Двоичный формат с плавающей запятой двойной точности IEEE 754:binary64
Двоичные числа с плавающей запятой двойной точности — это широко используемый формат на ПК из-за его более широкого диапазона по сравнению с плавающей запятой одинарной точности, несмотря на его производительность и стоимость полосы пропускания. Он широко известен просто как double . Стандарт IEEE 754 определяет двоичный файл 64 как имеющий:
- Знаковый бит : 1 бит
- Экспонента : 11 бит
- значащего числа Точность : 53 бита (52 хранятся явно)
Знаковый бит определяет знак числа (в том числе, когда это число равно нулю, что обозначается знаком ).
Поле экспоненты представляет собой 11-битное целое число без знака от 0 до 2047 в смещенной форме : значение экспоненты 1023 представляет фактический ноль. Показатели степени варьируются от -1022 до +1023, поскольку показатели степени -1023 (все 0) и +1024 (все 1) зарезервированы для специальных чисел.
53-битная точность мантиссы обеспечивает точность от 15 до 17 значащих десятичных цифр (2 −53 ≈ 1.11 × 10 −16 ). Если десятичная строка, содержащая не более 15 значащих цифр, преобразуется в формат двойной точности IEEE 754, давая нормальное число, а затем преобразуется обратно в десятичную строку с тем же количеством цифр, конечный результат должен соответствовать исходной строке. Если число двойной точности IEEE 754 преобразуется в десятичную строку, содержащую не менее 17 значащих цифр, а затем преобразуется обратно в представление двойной точности, конечный результат должен соответствовать исходному числу. [1]
В формате мантисса имеет неявный целочисленный бит со значением 1 (за исключением специальных данных, см. кодировку экспоненты ниже). Таким образом, поскольку в формате памяти присутствуют 52 бита мантиссы дроби (F), общая точность составляет 53 бита (приблизительно 16 десятичных цифр, 53 log 10 (2) ≈ 15,955). Биты расположены следующим образом:
Реальное значение, предполагаемое заданными 64-битными данными двойной точности с заданным смещенным показателем степени. и 52-битная дробь
или
Между 2 52 =4 503 599 627 370 496 и 2 53 =9 007 199 254 740 992 представимые числа являются в точности целыми числами. Для следующего диапазона от 2 53 до 2 54 , все умножается на 2, поэтому представимые числа — четные и т. д. И наоборот, для предыдущего диапазона от 2 51 до 2 52 , интервал равен 0,5 и т. д.
Расстояние как доля чисел в диапазоне от 2 н до 2 п +1 2 п -52 . Таким образом, максимальная относительная ошибка округления при округлении числа до ближайшего представимого ( машинного эпсилона ) равна 2. −53 .
Ширина экспоненты составляет 11 бит, что позволяет представлять числа от 10 до 10. −308 и 10 308 , с полной точностью до 15–17 десятичных цифр. В ущерб точности субнормальное представление допускает еще меньшие значения, примерно до 5 × 10. −324 .
Экспоненциальное кодирование
Двоичная экспонента с плавающей запятой двойной точности кодируется с использованием двоичного представления смещения , при этом нулевое смещение равно 1023; также известное как смещение экспоненты в стандарте IEEE 754. Примерами таких представлений могут быть:
и = 000000000012 = 00116 =1:
|
(наименьший показатель степени для нормальных чисел ) | ||
и = 011111111112 = 3ff16 =1023:
|
(смещение нуля) | ||
и = 100000001012 = 40516 =1029:
|
|||
и = 111111111102 = 7fe16 =2046:
|
(наивысший показатель) |
Экспоненты 00016
и 7ff16
имеют особое значение:
000000000002
=00016
используется для представления знакового нуля (если F = 0) и субнормальных чисел (если F ≠ 0); и111111111112
=7ff16
используется для представления ∞ (если F = 0) и NaN (если F ≠ 0),
где F — дробная часть мантиссы . Все битовые комбинации являются допустимой кодировкой.
За исключением вышеуказанных исключений, все число двойной точности описывается следующим образом:
В случае субнормальных чисел ( e = 0) число двойной точности описывается следующим образом:
Порядок байтов
Примеры двойной точности
0 01111111111 000000000000000000000000000000000000000000000000000 2 ≙ 3FF0 0000 0000 0000 16 ≙ +2 0 × 1 = 1 |
0 01111111111 000000000000000000000000000000000000000000000000001 2 ≙ 3FF0 0000 0000 0001 16 ≙ +2 0 × (1 + 2 −52 ) ≈ 1,0000000000000002, наименьшее число > 1 |
0 01111111111 0000000000000000000000000000000000000000000000000010 2 ≙ 3FF0 0000 0000 0002 16 ≙ +2 0 × (1 + 2 −51 ) ≈ 1.0000000000000004 |
0 10000000000 0000000000000000000000000000000000000000000000000000 2 ≙ 4000 0000 0000 0000 16 ≙ +2 1 × 1 = 2 |
1 10000000000 000000000000000000000000000000000000000000000000000 2 ≙ C000 0000 0000 0000 16 ≙ −2 1 × 1 = −2 |
0 10000000000 1000000000000000000000000000000000000000000000000000 2 ≙ 4008 0000 0000 0000 16 ≙ +2 1 × 1.1 2 = 11 2 = 3 |
0 10000000001 0000000000000000000000000000000000000000000000000000 2 ≙ 4010 0000 0000 0000 16 ≙ +2 2 × 1 = 100 2 = 4 |
0 10000000001 0100000000000000000000000000000000000000000000000000 2 ≙ 4014 0000 0000 0000 16 ≙ +2 2 × 1.01 2 = 101 2 = 5 |
0 10000000001 1000000000000000000000000000000000000000000000000000 2 ≙ 4018 0000 0000 0000 16 ≙ +2 2 × 1.1 2 = 110 2 = 6 |
0 10000000011 0111000000000000000000000000000000000000000000000000 2 ≙ 4037 0000 0000 0000 16 ≙ +2 4 × 1.0111 2 = 10111 2 = 23 |
0 01111111000 1000000000000000000000000000000000000000000000000000 2 ≙ 3F88 0000 0000 0000 16 ≙ +2 −7 × 1.1 2 = 0.00000011 2 = 0.01171875 (3/256) |
0 00000000000 0000000000000000000000000000000000000000000000000001 2 ≙ 0000 0000 0000 0001 16 ≙ +2 −1022 × 2 −52 = 2 −1074 ≈ 4.9406564584124654 × 10 −324 (Мин. субнормальный положительный двойной) |
0 00000000000 1111111111111111111111111111111111111111111111111111 2 ≙ 000F FFFF FFFF FFFF 16 ≙ +2 −1022 × (1 − 2 −52 ) ≈ 2.2250738585072009 × 10 −308 (Макс. субнормальный двойной) |
0 00000000001 0000000000000000000000000000000000000000000000000000 2 ≙ 0010 0000 0000 0000 16 ≙ +2 −1022 × 1 ≈ 2.2250738585072014 × 10 −308 (Мин. нормальный положительный двойной) |
0 11111111110 11111111111111111111111111111111111111111111111111111 2 ≙ 7FEF FFFF FFFF FFFF 16 ≙ +2 1023 × (1 + (1 − 2 −52 )) ≈ 1.7976931348623157 × 10 308 (Макс. двойной) |
0 00000000000 0000000000000000000000000000000000000000000000000000 2 ≙ 0000 0000 0000 0000 16 ≙ +0 |
1 00000000000 0000000000000000000000000000000000000000000000000000 2 ≙ 8000 0000 0000 0000 16 ≙ −0 |
0 11111111111 000000000000000000000000000000000000000000000000000 2 ≙ 7FF0 0000 0000 0000 16 ≙ +∞ (положительная бесконечность) |
1 11111111111 000000000000000000000000000000000000000000000000000 2 ≙ FFF0 0000 0000 0000 16 ≙ −∞ (отрицательная бесконечность) |
0 11111111111 000000000000000000000000000000000000000000000000001 2 ≙ 7FF0 0000 0000 0001 16 ≙ NaN (sNaN на большинстве процессоров, таких как x86 и ARM) |
0 11111111111 1000000000000000000000000000000000000000000000000001 2 ≙ 7FF8 0000 0000 0001 16 ≙ NaN (qNaN на большинстве процессоров, таких как x86 и ARM) |
0 11111111111 111111111111111111111111111111111111111111111111111 2 ≙ 7FFF FFFF FFFF FFFF 16 ≙ NaN (альтернативное кодирование NaN) |
0 01111111101 0101010101010101010101010101010101010101010101010101 2 = 3FD5 5555 5555 5555 16 ≙ +2 −2 × (1 + 2 −2 + 2 −4 + ... + 2 −52 ) ≈ 1 / 3 |
0 10000000000 1001001000011111101101010100010001000010110100011000 2 = 4009 21FB 5444 2D18 16 ≈ пи |
Кодировки qNaN и sNaN не полностью определены в IEEE 754 и зависят от процессора. Большинство процессоров, таких как процессоры семейства x86 и семейства ARM , используют старший бит поля мантиссы для обозначения тихого NaN; это то, что рекомендует стандарт IEEE 754. Процессоры PA-RISC используют этот бит для обозначения сигнального NaN.
По умолчанию, 1 / 3 округления вниз, а не вверх, как при одинарной точности , из-за нечетного числа битов в мантиссе.
Более подробно:
Given the hexadecimal representation 3FD5 5555 5555 555516, Sign = 0 Exponent = 3FD16 = 1021 Exponent Bias = 1023 (constant value; see above) Fraction = 5 5555 5555 555516 Value = 2(Exponent − Exponent Bias) × 1.Fraction – Note that Fraction must not be converted to decimal here = 2−2 × (15 5555 5555 555516 × 2−52) = 2−54 × 15 5555 5555 555516 = 0.333333333333333314829616256247390992939472198486328125 ≈ 1/3
Скорость выполнения при арифметике двойной точности
Использование переменных с плавающей запятой двойной точности обычно медленнее, чем работа с их аналогами одинарной точности. Одной из областей вычислений, где это является особой проблемой, является параллельный код, выполняемый на графических процессорах. Например, при использовании платформы NVIDIA CUDA вычисления с двойной точностью могут занять, в зависимости от оборудования, от 2 до 32 раз больше времени по сравнению с вычислениями с одинарной точностью . [4]
Кроме того, многие математические функции (например, sin, cos, atan2, log, exp и sqrt) требуют большего количества вычислений для получения точных результатов двойной точности и поэтому работают медленнее.
Ограничения точности целочисленных значений
- Целые числа от −2 53 до 2 53 (от -9 007 199 254 740 992 до 9 007 199 254 740 992) могут быть точно представлены.
- Целые числа между 2 53 и 2 54 = 18 014 398 509 481 984 округляем до кратного 2 (четное число).
- Целые числа между 2 54 и 2 55 = 36 028 797 018 963 968 округляем до числа, кратного 4.
- Целые числа между 2 н и 2 п +1 округлить до кратного 2 п -52 .
Реализации
Двойники реализуются во многих языках программирования по-разному, например, следующим образом. На процессорах только с динамической точностью, например x86 без SSE2 (или когда SSE2 не используется в целях совместимости) и с расширенной точностью, используемой по умолчанию, у программного обеспечения могут возникнуть трудности с выполнением некоторых требований.
С и С++
C и C++ предлагают большое разнообразие арифметических типов . Двойная точность не требуется стандартами (за исключением дополнительного приложения F к C99 , охватывающего арифметику IEEE 754), но в большинстве систем double
тип соответствует двойной точности. Однако в 32-разрядной версии x86 с повышенной точностью по умолчанию некоторые компиляторы могут не соответствовать стандарту C или арифметика может страдать от двойного округления . [5]
Фортран
Фортран предоставляет несколько целочисленных и вещественных типов, а также 64-битный тип. real64
, доступный через встроенный модуль Фортрана iso_fortran_env
, соответствует двойной точности.
Общий Лисп
Common Lisp предоставляет типы SHORT-FLOAT, SINGLE-FLOAT, DOUBLE-FLOAT и LONG-FLOAT. Большинство реализаций предоставляют SINGLE-FLOAT и DOUBLE-FLOAT с соответствующими синонимами других типов. Common Lisp предоставляет исключения для перехвата переполнений и переполнений с плавающей запятой, а также исключения неточных чисел с плавающей запятой, согласно IEEE 754. В стандарте ANSI не описаны бесконечности и NaN, однако некоторые реализации предоставляют их как расширения.
Ява
В Java до версии 1.2 каждая реализация должна была соответствовать стандарту IEEE 754. Версия 1.2 позволила реализациям повысить точность промежуточных вычислений для таких платформ, как x87 . Таким образом, был введен модификатор strictfp для обеспечения строгих вычислений IEEE 754. Строгая плавающая запятая была восстановлена в Java 17. [6]
JavaScript
Согласно стандарту ECMAScript , вся арифметика в JavaScript должна выполняться с использованием арифметики с плавающей запятой двойной точности. [7]
JSON
Формат кодирования данных JSON поддерживает числовые значения, а грамматика, которой должны соответствовать числовые выражения, не имеет ограничений на точность или диапазон закодированных таким образом чисел. Однако в RFC 8259 сообщается, что, поскольку числа двоичного формата IEEE 754 широко распространены, хорошая совместимость может быть достигнута за счет реализации обработки JSON, если они не ожидают большей точности или диапазона, чем предлагает двоичный64. [8]
Примечания и ссылки
- ^ Уильям Кахан (1 октября 1997 г.). «Конспекты лекций о статусе стандарта IEEE 754 для двоичной арифметики с плавающей запятой» (PDF) . п. 4. Архивировано (PDF) из оригинала 8 февраля 2012 г.
- ^ Савард, Джон Дж. Г. (2018) [2005], «Форматы с плавающей запятой» , четырехблок , заархивировано из оригинала 03 июля 2018 г. , получено 16 июля 2018 г.
- ^ «упаковать – преобразовать список в двоичное представление» . Архивировано из оригинала 18 февраля 2009 г. Проверено 4 февраля 2009 г.
- ^ «Новый Titan V от NVIDIA обеспечивает производительность одного чипа 110 терафлопс» . Аппаратное обеспечение Тома . 08.12.2017 . Проверено 5 ноября 2018 г.
- ^ «Ошибка 323 – оптимизированный код дает странные результаты с плавающей запятой» . gcc.gnu.org . Архивировано из оригинала 30 апреля 2018 года . Проверено 30 апреля 2018 г.
- ^ Дарси, Джозеф Д. «JEP 306: восстановить всегда строгую семантику с плавающей запятой» . Проверено 12 сентября 2021 г.
- ^ ECMA-262 Спецификация языка ECMAScript (PDF) (5-е изд.). Экма Интернешнл. п. 29, §8.5 Тип номера . Архивировано (PDF) из оригинала 13 марта 2012 г.
- ^ «Формат обмена данными нотации объектов JavaScript (JSON)» . Рабочая группа по интернет-инжинирингу. Декабрь 2017 года . Проверено 1 февраля 2022 г.