stringtranslate.com

Формат с плавающей точкой двойной точности

Формат чисел с плавающей точкой двойной точности (иногда называемый 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.

Двоичный формат с плавающей точкой двойной точности IEEE 754: binary64

Формат с плавающей точкой двойной точности является широко используемым форматом на ПК из-за его более широкого диапазона по сравнению с плавающей точкой одинарной точности, несмотря на его производительность и стоимость полосы пропускания. Он обычно известен просто как 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. Примерами таких представлений могут быть:

Показатели степеней и имеют особое значение:000167ff16

где F — дробная часть значащей части . Все битовые комбинации являются допустимой кодировкой.

За исключением приведенных выше исключений, все число двойной точности описывается следующим образом:

В случае субнормальных чисел ( e = 0) число двойной точности описывается следующим образом:

Порядковый номер байтов

Хотя многие процессоры используют хранение с прямым порядком байтов для всех типов данных (целые числа, числа с плавающей точкой), существует ряд аппаратных архитектур, в которых числа с плавающей точкой представлены в форме с прямым порядком байтов, а целые числа — в форме с прямым порядком байтов. [2] Существуют процессоры ARM , которые имеют смешанное представление с плавающей точкой для чисел двойной точности: каждое из двух 32-битных слов хранится как с прямым порядком байтов, но самое значимое слово хранится первым. VAX с плавающей точкой хранит 16-битные слова с прямым порядком байтов в порядке с прямым порядком байтов. Поскольку существует множество форматов с плавающей точкой без сетевого стандартного представления для них, стандарт XDR использует в качестве своего представления IEEE 754 с прямым порядком байтов. Поэтому может показаться странным, что широко распространенный стандарт с плавающей точкой IEEE 754 не определяет порядок байтов. [3] Теоретически это означает, что даже стандартные данные с плавающей точкой IEEE, записанные одной машиной, могут быть нечитаемы другой. Однако на современных стандартных компьютерах (т. е. реализующих IEEE 754) можно смело предположить, что порядок байтов для чисел с плавающей точкой и целых чисел одинаковы, что делает преобразование простым независимо от типа данных. Однако небольшие встроенные системы, использующие специальные форматы с плавающей точкой, могут быть другим вопросом.

Примеры двойной точности

Кодировки 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]

JavaScript

Как указано в стандарте ECMAScript , все арифметические операции в JavaScript должны выполняться с использованием арифметики с плавающей точкой двойной точности. [7]

JSON

Формат кодирования данных JSON поддерживает числовые значения, а грамматика, которой должны соответствовать числовые выражения, не имеет ограничений по точности или диапазону чисел, закодированных таким образом. Однако RFC 8259 рекомендует, что, поскольку числа IEEE 754 binary64 широко реализованы, можно добиться хорошей совместимости с помощью реализаций, обрабатывающих JSON, если они не ожидают большей точности или диапазона, чем предлагает binary64. [8]

Раст и Зиг

Rust и Zig имеют f64тип данных. [9] [10]

Примечания и ссылки

  1. Уильям Кахан (1 октября 1997 г.). «Конспект лекций о состоянии стандарта IEEE 754 для двоичной арифметики с плавающей точкой» (PDF) . стр. 4. Архивировано (PDF) из оригинала 8 февраля 2012 г.
  2. ^ Savard, John JG (2018) [2005], «Форматы с плавающей точкой», quadibloc , заархивировано из оригинала 2018-07-03 , извлечено 2018-07-16
  3. ^ "pack – преобразовать список в двоичное представление". Архивировано из оригинала 2009-02-18 . Получено 2009-02-04 .
  4. ^ "Nvidia's New Titan V выдает 110 терафлопс с одного чипа". Tom's Hardware . 2017-12-08 . Получено 2018-11-05 .
  5. ^ "Ошибка 323 – оптимизированный код дает странные результаты с плавающей точкой". gcc.gnu.org . Архивировано из оригинала 30 апреля 2018 г. . Получено 30 апреля 2018 г. .
  6. ^ Дарси, Джозеф Д. "JEP 306: Восстановление всегда строгой семантики чисел с плавающей точкой" . Получено 12 сентября 2021 г.
  7. ^ ECMA-262 ECMAScript Language Specification (PDF) (5-е изд.). Ecma International. стр. 29, §8.5 Тип числа . Архивировано (PDF) из оригинала 2012-03-13.
  8. ^ "Формат обмена данными JavaScript Object Notation (JSON)". Internet Engineering Task Force. Декабрь 2017 г. Получено 2022-02-01 .
  9. ^ "Типы данных - Язык программирования Rust". doc.rust-lang.org . Получено 10 августа 2024 г. .
  10. ^ "Документация - Язык программирования Zig". ziglang.org . Получено 10 августа 2024 г. .