Формат чисел с плавающей точкой двойной точности (иногда называемый FP64 или float64 ) — это формат чисел с плавающей точкой , обычно занимающий 64 бита в памяти компьютера; он представляет широкий диапазон числовых значений с использованием плавающей точки .
Двойную точность можно выбрать, когда диапазон или точность одинарной точности недостаточны.
В стандарте IEEE 754 64-битный формат с основанием 2 официально называется binary64 ; в IEEE 754-1985 он назывался double . IEEE 754 определяет дополнительные форматы с плавающей точкой, включая 32-битные форматы с основанием 2 одинарной точности и, в последнее время, форматы с основанием 10 ( десятичные форматы с плавающей точкой ).
Одним из первых языков программирования, предоставляющих типы данных с плавающей точкой, был Fortran . [ требуется ссылка ] До широкого принятия IEEE 754-1985 представление и свойства типов данных с плавающей точкой зависели от производителя и модели компьютера, а также от решений, принимаемых разработчиками языка программирования. Например, тип данных двойной точности GW-BASIC представлял собой 64-битный формат с плавающей точкой MBF.
Формат двоичных чисел с плавающей точкой двойной точности является широко используемым форматом на ПК из-за его более широкого диапазона по сравнению с плавающей точкой одинарной точности, несмотря на его производительность и стоимость полосы пропускания. Он обычно известен просто как double . Стандарт IEEE 754 определяет binary64 как имеющий:
Знаковый бит определяет знак числа (в том числе, когда это число равно нулю, что является знаковым ).
Поле экспоненты представляет собой 11-битное целое число без знака от 0 до 2047 в смещенной форме : значение экспоненты 1023 представляет фактический ноль. Экспоненты находятся в диапазоне от −1022 до +1023, поскольку экспоненты −1023 (все нули) и +1024 (все единицы) зарезервированы для специальных чисел.
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 n до 2 n +1 равно 2 n −52 . Максимальная относительная ошибка округления при округлении числа до ближайшего представимого ( машинного эпсилона ) составляет, таким образом, 2 −53 .
Ширина показателя степени в 11 бит позволяет представлять числа от 10 −308 до 10 308 с точностью до 15–17 десятичных знаков. Снижая точность, субнормальное представление допускает даже меньшие значения вплоть до 5 × 10 −324 .
Двоичная экспонента с плавающей точкой двойной точности кодируется с использованием двоично-смещенного представления, при этом нулевое смещение равно 1023; также известное как смещение экспоненты в стандарте IEEE 754. Примерами таких представлений могут быть:
Показатели степеней и имеют особое значение:00016
7ff16
000000000002
= используется для представления знакового нуля (если F = 0) и субнормальных чисел (если F ≠ 0); и00016
111111111112
= используется для представления ∞ (если F = 0) и NaN (если F ≠ 0),7ff16
где F — дробная часть значащей части . Все битовые комбинации являются допустимой кодировкой.
За исключением приведенных выше исключений, все число двойной точности описывается следующим образом:
В случае субнормальных чисел ( e = 0) число двойной точности описывается следующим образом:
Кодировки qNaN и sNaN не полностью определены в IEEE 754 и зависят от процессора. Большинство процессоров, таких как семейство x86 и процессоры семейства ARM , используют старший бит поля мантиссы для указания тихого NaN; это то, что рекомендуется IEEE 754. Процессоры PA-RISC используют бит для указания сигнального NaN.
По умолчанию 1 / 3 округляет в меньшую сторону, а не в большую, как при одинарной точности , из-за нечетного количества бит в значащей части.
Более подробно:
Учитывая шестнадцатеричное представление 3FD5 5555 5555 5555 16 , Знак = 0 Экспонента = 3FD 16 = 1021 Смещение показателя степени = 1023 (постоянное значение; см. выше) Дробь = 5 5555 5555 5555 16 Значение = 2 (Экспонента − Смещение экспоненты) × 1. Дробь — обратите внимание, что дробь не должна быть преобразована в десятичную здесь. = 2 −2 × (15 5555 5555 5555 16 × 2 −52 ) = 2 −54 × 15 5555 5555 5555 16 = 0,333333333333333314829616256247390992939472198486328125 ≈ 1/3
Использование переменных с плавающей точкой двойной точности обычно медленнее, чем работа с их аналогами с одинарной точностью. Одной из областей вычислений, где это является особой проблемой, является параллельный код, работающий на графических процессорах. Например, при использовании платформы NVIDIA CUDA вычисления с двойной точностью могут занять, в зависимости от оборудования, от 2 до 32 раз больше времени по сравнению с вычислениями с одинарной точностью . [4]
Кроме того, многие математические функции (например, sin, cos, atan2, log, exp и sqrt) требуют больше вычислений для получения точных результатов с двойной точностью и, следовательно, работают медленнее.
Двойные числа реализованы во многих языках программирования разными способами, например, следующими. На процессорах только с динамической точностью, таких как x86 без SSE2 (или когда SSE2 не используется в целях совместимости) и с расширенной точностью, используемой по умолчанию, программное обеспечение может испытывать трудности с выполнением некоторых требований.
C и C++ предлагают широкий спектр арифметических типов . Двойная точность не требуется стандартами (за исключением необязательного приложения F C99 , охватывающего арифметику IEEE 754), но в большинстве систем double
тип соответствует двойной точности. Однако на 32-битной x86 с расширенной точностью по умолчанию некоторые компиляторы могут не соответствовать стандарту C или арифметика может страдать от двойного округления . [5]
Fortran предоставляет несколько целочисленных и действительных типов, а 64-битный тип real64
, доступный через встроенный модуль Fortran 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]
Как указано в стандарте ECMAScript , все арифметические операции в JavaScript должны выполняться с использованием арифметики с плавающей точкой двойной точности. [7]
Формат кодирования данных JSON поддерживает числовые значения, а грамматика, которой должны соответствовать числовые выражения, не имеет ограничений на точность или диапазон чисел, закодированных таким образом. Однако RFC 8259 рекомендует, что, поскольку числа IEEE 754 binary64 широко реализованы, можно добиться хорошей совместимости с помощью реализаций, обрабатывающих JSON, если они не ожидают большей точности или диапазона, чем предлагает binary64. [8]
Rust и Zig имеют f64
тип данных. [9] [10]