stringtranslate.com

Арифметика с плавающей точкой

Один из первых электромеханических программируемых компьютеров Z3 включал в себя арифметику с плавающей точкой (копия экспонируется в Немецком музее в Мюнхене ).

В вычислительной технике арифметика с плавающей точкой ( FP ) в некоторой базе (или системе счисления счисления ) — это арифметика , которая представляет подмножества действительных чисел с использованием значения с фиксированной точкой (называемого мантиссом ) в этой базе с фиксированной точностью, масштабируемой целой степенью (определяемой показателем) этой базы. Числа этой формы называются числами с плавающей точкой . [1] : 3  [2] : 10 

Например, 12,345 можно записать в формате с плавающей точкой в ​​десятичной системе счисления с точностью до пяти цифр: выбрав запись значащей части с десятичной точкой после пятой цифры. Однако, в отличие от 12,345, 12,3456 нельзя записать в пятизначном формате с плавающей точкой в ​​десятичной системе счисления, для этого требуется точность до шести цифр. Ближайшее число с плавающей точкой, содержащее всего пять цифр, — это 12,346. На практике большинство систем с плавающей точкой используют основание два , хотя основание десять ( десятичное с плавающей точкой ) также распространено.

Арифметические операции с плавающей точкой, такие как сложение и деление, приближают соответствующие арифметические операции с действительными числами, округляя любой результат, который сам по себе не является числом с плавающей точкой, до ближайшего числа с плавающей точкой. [1] : 22  [2] : 10  Например, в арифметике с плавающей точкой с точностью пять десятичных знаков сумма 12,345 + 1,0001 = 13,3451 может быть округлена до 13,345.

Термин «плавающая точка» относится к тому факту, что точка основания числа может «плавать» где угодно слева, справа или между значимыми цифрами числа. Эта позиция указывается экспонентой, поэтому плавающую точку можно считать формой научной записи .

Система с плавающей точкой может использоваться для представления с фиксированным числом цифр чисел самых разных порядков величины — например, числа метров между галактиками или между протонами в атоме . По этой причине арифметика с плавающей точкой часто используется для разрешения очень маленьких и очень больших действительных чисел, требующих быстрого времени обработки. Результатом этого динамического диапазона является то, что числа, которые могут быть представлены, неравномерно распределены; разница между двумя последовательными представимыми числами меняется в зависимости от их показателя степени. [3]

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

На протяжении многих лет в компьютерах использовались различные представления с плавающей точкой. В 1985 году был установлен стандарт IEEE 754 для арифметики с плавающей точкой, а с 1990-х годов наиболее часто встречающимися представлениями являются те, которые определены IEEE.

Скорость операций с плавающей точкой, обычно измеряемая в единицах FLOPS , является важной характеристикой компьютерной системы , особенно для приложений, требующих интенсивных математических вычислений.

Устройство с плавающей точкой (FPU, в просторечии математический сопроцессор ) — это часть компьютерной системы, специально разработанная для выполнения операций с числами с плавающей точкой.

Обзор

Числа с плавающей точкой

Представление числа определяет некоторый способ кодирования числа, обычно в виде строки цифр.

Существует несколько механизмов, с помощью которых строки цифр могут представлять числа. В стандартной математической нотации строка цифр может быть любой длины, а местоположение точки основания указывается путем размещения там явного символа «точки» (точки или запятой). Если точка основания не указана, то строка неявно представляет целое число , а неуказанная точка основания будет находиться за правым концом строки, рядом с наименее значащей цифрой. В системах с фиксированной точкой позиция в строке указывается для точки основания. Таким образом, схема с фиксированной точкой может использовать строку из 8 десятичных цифр с десятичной точкой посередине, в результате чего «00012345» будет представлять 0001.2345.

В научной нотации заданное число масштабируется степенью 10 , так что оно находится в определенном диапазоне — обычно между 1 и 10, с точкой основания, появляющейся сразу после первой цифры. Как степень десяти, коэффициент масштабирования затем указывается отдельно в конце числа. Например, орбитальный период спутника Юпитера Ио равен152 853,5047 секунд, значение, которое в стандартной форме научной записи будет представлено как1,528535047 × 10 5 секунд.

Представление с плавающей точкой по своей концепции похоже на научную запись. Логически число с плавающей точкой состоит из:

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

Используя в качестве примера основание 10 (знакомую десятичную систему счисления), числоЧисло 152,853.5047 , имеющее десять десятичных знаков точности, представлено как значащая часть1 528 535 047 вместе с 5 в качестве показателя степени. Для определения фактического значения десятичная точка ставится после первой цифры значащей части, а результат умножается на 105 дать1,528535047 × 10 5 , или152 853,5047 . При сохранении такого числа основание (10) хранить не нужно, поскольку оно будет одинаковым для всего диапазона поддерживаемых чисел и, таким образом, может быть выведено.

Символически это конечное значение равно:

где s — мантисса (игнорируя любую подразумеваемую десятичную точку), p — точность (количество цифр в мантиссе), b — основание (в нашем примере это число десять ), а e — показатель степени.

Исторически для представления чисел с плавающей точкой использовалось несколько систем счисления, при этом наиболее распространенной является система счисления с основанием два ( двоичная ), за которой следует система счисления с основанием десять ( десятичная с плавающей точкой ), а также другие менее распространенные разновидности, такие как система счисления с основанием шестнадцать ( шестнадцатеричная с плавающей точкой [4] [5] [nb 3] ), система с основанием восемь (восьмеричная с плавающей точкой [1] [5] [6] [4] [nb 4] ), система с основанием четыре (четвертичная с плавающей точкой [7] [5] [nb 5] ), система с основанием три ( сбалансированная троичная с плавающей точкой [1] ) и даже система с основанием 256 [5] [nb 6] и система с основанием65 536 . [8] [прим. 7]

Число с плавающей точкой является рациональным числом , поскольку его можно представить как одно целое число, деленное на другое; например1,45 × 10 3 равно (145/100)×1000 или145 000 / 100. Основание определяет дроби, которые могут быть представлены; например, 1/5 не может быть точно представлено как число с плавающей точкой с использованием двоичного основания, но 1/5 может быть точно представлено с использованием десятичного основания (0,2 или2 × 10 −1 ). Однако 1/3 не может быть точно представлена ​​ни двоичной (0,010101...), ни десятичной (0,333...), но в системе счисления с основанием 3 она тривиальна (0,1 или 1×3 −1 ) . Случаи, когда происходят бесконечные расширения, зависят от основания и его простых множителей .

Способ, которым мантисса (включая ее знак) и показатель степени хранятся в компьютере, зависит от реализации. Общие форматы IEEE подробно описаны позже и в другом месте, но в качестве примера, в двоичном представлении с плавающей точкой одинарной точности (32 бита), и поэтому мантисса представляет собой строку из 24 бит . Например, первые 33 бита числа π следующие:

В этом двоичном расширении обозначим позиции от 0 (самый левый бит или самый значимый бит) до 32 (самый правый бит). 24-битная мантисса остановится на позиции 23, показанной как подчеркнутый бит0 выше. Следующий бит, в позиции 24, называется битом округления или битом округления . Он используется для округления 33-битного приближения до ближайшего 24-битного числа (существуют особые правила для половинных значений , что в данном случае не так). Этот бит, которыйВ этом примере 1 добавляется к целому числу, образованному крайними левыми 24 битами, что дает:

Когда это сохраняется в памяти с использованием кодировки IEEE 754, это становится мантиссом s . Предполагается, что мантисса имеет двоичную точку справа от самого левого бита. Таким образом, двоичное представление π вычисляется слева направо следующим образом:

где p — точность (24 в этом примере), n — это позиция бита мантиссы слева (начиная с0 и заканчивая на23 здесь) и e - показатель степени (1 в этом примере).

Можно потребовать, чтобы старший разряд мантиссы ненулевого числа был ненулевым (за исключением случаев, когда соответствующая экспонента будет меньше минимальной). Этот процесс называется нормализацией . Для двоичных форматов (которые используют только цифры0 и1 ), эта ненулевая цифра обязательно1 . Поэтому его не нужно представлять в памяти, что позволяет формату иметь еще один бит точности. Это правило по-разному называется соглашением о ведущих битах , неявным соглашением о битах , скрытым соглашением о битах [1] или предполагаемым соглашением о битах .

Альтернативы числам с плавающей точкой

Представление с плавающей точкой является наиболее распространенным способом представления в компьютерах приближения к действительным числам. Однако существуют и альтернативы:

История

В 1914 году Леонардо Торрес Кеведо опубликовал анализ чисел с плавающей точкой, основанный на аналитической машине .

В 1914 году испанский инженер Леонардо Торрес Кеведо опубликовал «Очерки автоматики» [ 9] , где он спроектировал специализированный электромеханический калькулятор на основе аналитической машины Чарльза Бэббиджа и описал способ хранения чисел с плавающей точкой согласованным образом. Он заявил, что числа будут храниться в экспоненциальном формате как n x 10 , и предложил три правила, с помощью которых можно реализовать согласованную обработку чисел с плавающей точкой машинами. Для Торреса « n всегда будет иметь одинаковое количество цифр (например, шесть), первая цифра n будет иметь порядок десятых, вторая — сотых и т. д., и каждую величину следует записывать в виде: n ; m ». Предложенный им формат показывает необходимость фиксированного размера мантиссы, который в настоящее время используется для данных с плавающей точкой, фиксируя местоположение десятичной точки в мантиссе так, чтобы каждое представление было уникальным, и как форматировать такие числа, указывая используемый синтаксис, который можно было бы ввести с помощью пишущей машинки , как это было в случае его электромеханического арифмометра в 1920 году. [10] [11] [12]

Конрад Цузе , архитектор компьютера Z3 , который использует 22-битное двоичное представление с плавающей точкой

В 1938 году Конрад Цузе из Берлина завершил Z1 , первый двоичный программируемый механический компьютер ; [13] он использует 24-битное двоичное представление чисел с плавающей точкой с 7-битной знаковой экспонентой, 17-битной мантиссом (включая один неявный бит) и знаковым битом. [ 14] Более надежный релейный Z3 , завершенный в 1941 году, имеет представления как для положительных, так и для отрицательных бесконечностей; в частности, он реализует определенные операции с бесконечностью, такие как , и останавливается на неопределенных операциях, таких как .

Цузе также предложил, но не завершил, тщательно округленную арифметику с плавающей точкой, которая включает и представления NaN, предвосхищая возможности стандарта IEEE на четыре десятилетия. [15] Напротив, фон Нейман рекомендовал не использовать числа с плавающей точкой для машины IAS 1951 года , утверждая, что арифметика с фиксированной точкой предпочтительнее. [15]

Первым коммерческим компьютером с аппаратным обеспечением для работы с плавающей точкой был компьютер Z4 Цузе , разработанный в 1942–1945 годах. В 1946 году Bell Laboratories представила Model V , в которой были реализованы десятичные числа с плавающей точкой . [16]

Pilot ACE имеет двоичную арифметику с плавающей точкой, и она начала работать в 1950 году в Национальной физической лаборатории Великобритании . Тридцать три были позже проданы на коммерческой основе как English Electric DEUCE . Арифметика фактически реализована в программном обеспечении, но с тактовой частотой в один мегагерц скорость операций с плавающей точкой и фиксированной точкой в ​​этой машине изначально была выше, чем у многих конкурирующих компьютеров.

В 1954 году последовал массовый IBM 704 ; он ввел использование смещенной экспоненты . В течение многих десятилетий после этого аппаратное обеспечение с плавающей точкой обычно было дополнительной функцией, и компьютеры, которые имели ее, назывались «научными компьютерами» или имели возможность « научных вычислений » (SC) (см. также Расширения для научных вычислений (XSC)). Только с выпуском Intel i486 в 1989 году персональные компьютеры общего назначения имели аппаратную возможность с плавающей точкой в ​​качестве стандартной функции.

Серия UNIVAC 1100/2200 , представленная в 1962 году, поддерживала два представления чисел с плавающей точкой:

IBM 7094 , также представленный в 1962 году, поддерживал представления с одинарной и двойной точностью, но не имел никакого отношения к представлениям UNIVAC. Действительно, в 1964 году IBM представила шестнадцатеричные представления с плавающей точкой в ​​своих мэйнфреймах System/360 ; эти же представления по-прежнему доступны для использования в современных системах z/Architecture . В 1998 году IBM реализовала совместимую с IEEE двоичную арифметику с плавающей точкой в ​​своих мэйнфреймах; в 2005 году IBM также добавила совместимую с IEEE десятичную арифметику с плавающей точкой.

Первоначально компьютеры использовали много различных представлений для чисел с плавающей точкой. Отсутствие стандартизации на уровне мэйнфреймов было постоянной проблемой к началу 1970-х годов для тех, кто писал и поддерживал исходный код более высокого уровня; эти стандарты производителей для чисел с плавающей точкой различались по размерам слов, представлениям, поведению округления и общей точности операций. Совместимость с плавающей точкой между несколькими вычислительными системами отчаянно нуждалась в стандартизации к началу 1980-х годов, что привело к созданию стандарта IEEE 754, как только 32-битное (или 64-битное) слово стало обычным явлением. Этот стандарт был в значительной степени основан на предложении Intel, которая проектировала числовой сопроцессор i8087 ; Motorola, которая проектировала 68000 примерно в то же время, также внесла значительный вклад.

Уильям Кахан , главный архитектор стандарта IEEE 754 с плавающей точкой

В 1989 году математик и ученый-компьютерщик Уильям Кахан был удостоен премии Тьюринга за то, что он был главным архитектором этого предложения; ему помогали его студент Джером Кунен и приглашенный профессор Гарольд Стоун . [17]

Среди нововведений x86 можно выделить следующие:

Диапазон чисел с плавающей точкой

Число с плавающей точкой состоит из двух компонентов с фиксированной точкой , диапазон которых зависит исключительно от количества бит или цифр в их представлении. В то время как компоненты линейно зависят от своего диапазона, диапазон с плавающей точкой линейно зависит от диапазона мантиссы и экспоненциально от диапазона компонента экспоненты, что придает числу значительно более широкий диапазон.

В типичной компьютерной системе двоичное число с плавающей точкой двойной точности (64 бита) имеет коэффициент 53 бита (включая 1 подразумеваемый бит), показатель степени 11 бит и 1 знаковый бит. Поскольку 2 10 = 1024, полный диапазон положительных нормальных чисел с плавающей точкой в ​​этом формате составляет от 2 −1022  ≈ 2 × 10 −308 до приблизительно 2 1024  ≈ 2 × 10 308 .

Число обычных чисел с плавающей точкой в ​​системе ( B , P , L , U ), где

является .

Существует наименьшее положительное нормальное число с плавающей точкой,

Уровень подтопления = UFL = ,

где ведущая цифра — 1, остальные цифры — 0, а показатель степени — наименьшее возможное значение.

Существует самое большое число с плавающей точкой,

Уровень переполнения = OFL = ,

где B − 1 является значением для каждой цифры мантиссы и максимально возможным значением для показателя степени.

Кроме того, существуют представимые значения строго между −UFL и UFL. А именно, положительные и отрицательные нули , а также субнормальные числа .

IEEE 754: плавающая точка в современных компьютерах

IEEE стандартизировал компьютерное представление двоичных чисел с плавающей точкой в ​​IEEE 754 (он же IEC 60559) в 1985 году . Этому первому стандарту следуют почти все современные машины. Он был пересмотрен в 2008 году . Мейнфреймы IBM поддерживают собственный шестнадцатеричный формат с плавающей точкой IBM и десятичный формат с плавающей точкой IEEE 754-2008 в дополнение к двоичному формату IEEE 754. Серия Cray T90 имела версию IEEE, но SV1 по-прежнему использует формат с плавающей точкой Cray. [ необходима цитата ]

Стандарт предусматривает множество тесно связанных форматов, отличающихся лишь несколькими деталями. Пять из этих форматов называются базовыми форматами , а другие называются форматами расширенной точности и форматом расширяемой точности . Три формата особенно широко используются в компьютерном оборудовании и языках: [ необходима цитата ]

Увеличение точности представления с плавающей точкой обычно уменьшает количество накопленных ошибок округления, вызванных промежуточными вычислениями. [24] Другие форматы IEEE включают:

Любое целое число с абсолютным значением меньше 2 24 может быть точно представлено в формате одинарной точности, а любое целое число с абсолютным значением меньше 2 53 может быть точно представлено в формате двойной точности. Кроме того, может быть представлен широкий диапазон степеней 2, умноженных на такое число. Эти свойства иногда используются для чисто целочисленных данных, чтобы получить 53-битные целые числа на платформах, которые имеют числа с плавающей точкой двойной точности, но только 32-битные целые числа.

Стандарт определяет некоторые специальные значения и их представление: положительная бесконечность ( +∞ ), отрицательная бесконечность ( −∞ ), отрицательный ноль (−0), отличный от обычного («положительного») нуля, и значения «не число» ( NaN ).

Сравнение чисел с плавающей точкой, как определено стандартом IEEE, немного отличается от обычного сравнения целых чисел. Отрицательные и положительные нули сравниваются как равные, а каждое NaN сравнивается как неравное любому значению, включая себя. Все конечные числа с плавающей точкой строго меньше +∞ и строго больше −∞ , и они упорядочены так же, как и их значения (в наборе действительных чисел).

Внутреннее представительство

Числа с плавающей точкой обычно упаковываются в компьютерные данные как бит знака, поле экспоненты и мантиссу или мантиссу, слева направо. Для двоичных форматов IEEE 754 (базового и расширенного), которые имеют существующие аппаратные реализации, они распределяются следующим образом:

Хотя показатель степени может быть положительным или отрицательным, в двоичных форматах он хранится как беззнаковое число, к которому добавлено фиксированное «смещение». Значения всех нулей в этом поле зарезервированы для нулей и субнормальных чисел ; значения всех единиц зарезервированы для бесконечностей и NaN. Диапазон показателя степени для нормальных чисел составляет [−126, 127] для одинарной точности, [−1022, 1023] для двойной или [−16382, 16383] для четверной. Нормальные числа не включают субнормальные значения, нули, бесконечности и NaN.

В форматах двоичного обмена IEEE первый бит нормализованной мантиссы фактически не хранится в компьютерных данных. Он называется «скрытым» или «неявным» битом. Из-за этого формат одинарной точности на самом деле имеет мантису с точностью 24 бита, формат двойной точности — 53, а четверной — 113.

Например, выше было показано, что число π, округленное до точности 24 бит, имеет:

Сумма смещения показателя степени (127) и показателя степени (1) равна 128, поэтому в формате одинарной точности это представлено как

Пример макета для 32-битных чисел с плавающей точкой :

и 64-битная («двойная») раскладка аналогична.

Другие известные форматы с плавающей точкой

Помимо широко используемых стандартных форматов IEEE 754 , в некоторых предметно-ориентированных областях используются или использовались и другие форматы с плавающей точкой.

Представимые числа, преобразование и округление

По своей природе все числа, выраженные в формате с плавающей точкой, являются рациональными числами с конечным расширением в соответствующем основании (например, конечное десятичное расширение в основании 10 или конечное двоичное расширение в основании 2). Иррациональные числа, такие как π или √2, или неконечные рациональные числа, должны быть приближены. Количество цифр (или бит) точности также ограничивает набор рациональных чисел, которые могут быть представлены точно. Например, десятичное число 123456789 не может быть точно представлено, если доступны только восемь десятичных знаков точности (оно будет округлено до одного из двух представимых значений, 12345678 × 10 1 или 12345679 × 10 1 ), то же самое относится к неконечным цифрам (. 5 округляется до . 5555555 или . 55555556).

Когда число представлено в некотором формате (например, в виде строки символов), который не является собственным представлением с плавающей точкой, поддерживаемым в компьютерной реализации, то потребуется преобразование, прежде чем его можно будет использовать в этой реализации. Если число может быть представлено точно в формате с плавающей точкой, то преобразование будет точным. Если точного представления нет, то преобразование требует выбора, какое число с плавающей точкой использовать для представления исходного значения. Выбранное представление будет иметь значение, отличное от исходного, и скорректированное таким образом значение называется округленным значением .

Имеет ли рациональное число конечное расширение или нет, зависит от основания. Например, в десятичной системе счисления число 1/2 имеет конечное расширение (0,5), а число 1/3 — нет (0,333...). В двоичной системе счисления конечными являются только рациональные числа со знаменателями, являющимися степенями 2 (например, 1/2 или 3/16). Любое рациональное число со знаменателем, имеющим простой множитель, отличный от 2, будет иметь бесконечное двоичное расширение. Это означает, что числа, которые кажутся короткими и точными при записи в десятичном формате, могут нуждаться в аппроксимации при преобразовании в двоичный формат с плавающей точкой. Например, десятичное число 0,1 не может быть представлено в двоичном формате с плавающей точкой любой конечной точности; точное двоичное представление будет иметь последовательность «1100», продолжающуюся бесконечно:

е = −4; с = 1100110011001100110011001100110011...,

где, как и ранее, s — мантисса, а e — показатель степени.

При округлении до 24 бит это становится

е = −4; с = 110011001100110011001101,

что на самом деле составляет 0,100000001490116119384765625 в десятичной системе счисления.

В качестве еще одного примера, действительное число π , представленное в двоичной системе счисления как бесконечная последовательность битов, равно

11.0010010000111111011010101000100010000101101000110000100011010011...

но есть

11.0010010000111111011011

при округлении до точности 24 бита.

В двоичном представлении с плавающей точкой одинарной точности это представляется как s  = 1,10010010000111111011011 с e  = 1. Это имеет десятичное значение

3.141592 7410125732421875,

тогда как более точное приближение истинного значения π равно

3.14159265358979323846264338327950 ...

Результат округления отличается от истинного значения примерно на 0,03 миллионных частей и соответствует десятеричному представлению числа π в первых 7 цифрах. Разница является ошибкой дискретизации и ограничена машинным эпсилоном .

Арифметическая разность между двумя последовательными представимыми числами с плавающей точкой, имеющими одинаковую экспоненту, называется единицей на последнем месте (ULP). Например, если нет представимого числа, лежащего между представимыми числами 1.45a70c22 hex и 1.45a70c24 hex , то ULP равно 2×16 −8 или 2 −31 . Для чисел с основанием 2 экспоненциальной части 0, т. е. чисел с абсолютным значением больше или равным 1, но меньше 2, ULP равно ровно 2 −23 или около 10 −7 в одинарной точности и ровно 2 −53 или около 10 −16 в двойной точности. Предписанное поведение IEEE-совместимого оборудования заключается в том, что результат должен быть в пределах половины ULP.

Режимы округления

Округление используется, когда для точного результата операции с плавающей точкой (или преобразования в формат с плавающей точкой) потребуется больше цифр, чем цифр в значащей части. IEEE 754 требует правильного округления : то есть округленный результат такой, как если бы для вычисления значения использовалась бесконечно точная арифметика, а затем округлялась (хотя в реализации для обеспечения этого требуется всего три дополнительных бита). Существует несколько различных схем округления (или режимов округления ). Исторически усечение было типичным подходом. С момента введения IEEE 754 чаще используется метод по умолчанию ( округление к ближайшему, привязка к четному , иногда называемый округлением банкира). Этот метод округляет идеальный (бесконечно точный) результат арифметической операции до ближайшего представимого значения и выдает это представление в качестве результата. [nb 8] В случае равенства выбирается значение, при котором значащая часть заканчивается четной цифрой. Стандарт IEEE 754 требует, чтобы одинаковое округление применялось ко всем фундаментальным алгебраическим операциям, включая квадратный корень и преобразования, когда есть числовой (не NaN) результат. Это означает, что результаты операций IEEE 754 полностью определены во всех битах результата, за исключением представления NaN. (Библиотечные" функции, такие как косинус и логарифм, не являются обязательными.)

Также доступны альтернативные варианты округления. IEEE 754 определяет следующие режимы округления:

Альтернативные режимы полезны, когда количество вносимой ошибки должно быть ограничено. Приложения, которым требуется ограниченная ошибка, — это многоточечная плавающая точка и интервальная арифметика . Альтернативные режимы округления также полезны при диагностике численной нестабильности: если результаты подпрограммы существенно различаются между округлением до + и − бесконечности, то она, скорее всего, численно нестабильна и подвержена ошибкам округления. [34]

Преобразование двоично-десятичного числа с минимальным количеством цифр

Преобразование двоичного числа с плавающей точкой двойной точности в десятичную строку является обычной операцией, но алгоритм, дающий результаты, которые являются как точными, так и минимальными, не появлялся в печати до 1990 года, когда Steele and White's Dragon4. Некоторые из усовершенствований с тех пор включают:

Многие современные среды выполнения языка используют Grisu3 с резервным вариантом Dragon4. [41]

Преобразование десятичных чисел в двоичные

Проблема разбора десятичной строки в двоичное представление FP является сложной, и точный анализатор не появлялся до работы Клингера 1990 года (реализованной в dtoa.c). [35] Дальнейшая работа также продвигалась в направлении более быстрого разбора. [42]

Операции с плавающей точкой

Для простоты представления и понимания в примерах будет использоваться десятичная система счисления с точностью 7 цифр, как в формате IEEE 754 decimal32 . Основные принципы одинаковы для любой системы счисления или точности, за исключением того, что нормализация необязательна (она не влияет на численное значение результата). Здесь s обозначает мантиссу, а e обозначает показатель степени.

Сложение и вычитание

Простой метод сложения чисел с плавающей точкой — сначала представить их с той же экспонентой. В примере ниже второе число (с меньшей экспонентой) сдвигается вправо на три цифры, а затем выполняется обычный метод сложения:

 123456,7 = 1,234567 × 10^5 101,7654 = 1,017654 × 10^2 = 0,001017654 × 10^5
 Следовательно: 123456,7 + 101,7654 = (1,234567 × 10^5) + (1,017654 × 10^2) = (1,234567 × 10^5) + (0,001017654 × 10^5) = (1,234567 + 0,001017654) × 10^5 = 1,235584654 × 10^5

Подробно:

 е=5; с=1,234567 (123456,7)+ е=2; с=1,017654 (101,7654)
 е=5; с=1,234567+ e=5; s=0,001017654 (после сдвига)-------------------- e=5; s=1,235584654 (истинная сумма: 123558,4654)

Это истинный результат, точная сумма операндов. Он будет округлен до семи цифр, а затем нормализован, если необходимо. Окончательный результат:

 е=5; s=1,235585 (конечная сумма: 123558,5)

Три младшие цифры второго операнда (654) по сути теряются. Это ошибка округления . В крайних случаях сумма двух ненулевых чисел может быть равна одному из них:

 е=5; с=1,234567+ е=−3; с=9,876543
 е=5; с=1,234567+ e=5; s=0,00000009876543 (после сдвига)---------------------- e=5; s=1,23456709876543 (истинная сумма) e=5; s=1,234567 (после округления и нормализации)

В приведенных выше концептуальных примерах может показаться, что сумматору необходимо предоставить большое количество дополнительных цифр для обеспечения правильного округления; однако для двоичного сложения или вычитания с использованием аккуратных методов реализации необходимо вынести за пределы точности операндов только защитный бит, бит округления и один дополнительный липкий бит. [43] [44] : 218–220 

Другая проблема потери значимости возникает, когда вычитаются приближения к двум почти равным числам. В следующем примере e  = 5; s  = 1,234571 и e  = 5; s  = 1,234567 являются приближениями к рациональным числам 123457,1467 и 123456,659.

 е=5; с=1,234571− е=5; с=1,234567---------------- е=5; с=0,000004 e=−1; s=4.000000 (после округления и нормализации)

Разница с плавающей точкой вычисляется точно, потому что числа близки — лемма Стербенца гарантирует это, даже в случае потери значимости, когда поддерживается постепенная потеря значимости . Несмотря на это, разница исходных чисел составляет e  = −1; s  = 4,877000, что отличается более чем на 20% от разницы e  = −1; s  = 4,000000 приближений. В крайних случаях все значимые цифры точности могут быть потеряны. [43] [45] Это сокращение иллюстрирует опасность предположения, что все цифры вычисленного результата имеют смысл. Борьба с последствиями этих ошибок является темой численного анализа ; см. также Проблемы точности.

Умножение и деление

При умножении мантиссы перемножаются, показатели степеней складываются, а результат округляется и нормализуется.

 е=3; с=4,734612× е=5; s=5,417242----------------------- e=8; s=25,648538980104 (истинное произведение) е=8; s=25,64854 (после округления) e=9; s=2,564854 (после нормализации)

Аналогично деление выполняется путем вычитания показателя степени делимого из показателя делителя и деления мантиссы делимого на мантиссу делителя.

При умножении или делении не возникает проблем с отменой или поглощением, хотя небольшие ошибки могут накапливаться по мере последовательного выполнения операций. [43] На практике способ выполнения этих операций в цифровой логике может быть довольно сложным (см. алгоритм умножения Бута и алгоритм деления ). [nb 9]

Буквальный синтаксис

Литералы для чисел с плавающей точкой зависят от языка. Обычно они используют eили Eдля обозначения научной нотации . Язык программирования C и стандарт IEEE 754 также определяют синтаксис шестнадцатеричного литерала с показателем степени по основанию 2 вместо 10. В таких языках, как C , когда десятичная экспонента опущена, десятичная точка необходима для их отличия от целых чисел. В других языках нет целочисленного типа (например, JavaScript ) или допускается перегрузка числовых типов (например, Haskell ). В этих случаях строки цифр, такие как , 123также могут быть литералами с плавающей точкой.

Примеры литералов с плавающей точкой:

Рассмотрение исключительных случаев

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

До появления стандарта IEEE такие условия обычно приводили к завершению программы или запускали своего рода ловушку , которую программист мог бы поймать. То, как это работало, зависело от системы, что означало, что программы с плавающей точкой не были переносимыми . (Термин «исключение», используемый в IEEE 754, является общим термином, означающим исключительное состояние, которое не обязательно является ошибкой, и отличается от того, что обычно определяется в языках программирования, таких как C++ или Java, в которых « исключение » является альтернативным потоком управления, ближе к тому, что называется «ловушкой» в терминологии IEEE 754.)

Здесь обсуждается требуемый метод обработки исключений по умолчанию в соответствии с IEEE 754 (необязательное перехватывание IEEE 754 и другие режимы «альтернативной обработки исключений» не обсуждаются). Арифметические исключения (по умолчанию) должны быть записаны в «липкие» биты флага состояния. То, что они «липкие», означает, что они не сбрасываются следующей (арифметической) операцией, а остаются установленными до явного сброса. Таким образом, использование «липких» флагов позволяет отложить проверку исключительных условий до завершения полного выражения с плавающей точкой или подпрограммы: без них исключительные условия, которые иначе нельзя было бы игнорировать, потребовали бы явной проверки сразу после каждой операции с плавающей точкой. По умолчанию операция всегда возвращает результат в соответствии со спецификацией, не прерывая вычислений. Например, 1/0 возвращает +∞, а также устанавливает бит флага деления на ноль (это значение по умолчанию ∞ предназначено для частого возврата конечного результата при использовании в последующих операциях, поэтому его можно безопасно игнорировать).

Однако исходный стандарт IEEE 754 не рекомендовал операции для обработки таких наборов битов флагов арифметических исключений. Поэтому, хотя они были реализованы в оборудовании, изначально реализации языков программирования обычно не предоставляли средств для доступа к ним (кроме ассемблера). Со временем некоторые стандарты языков программирования (например, C99 /C11 и Fortran) были обновлены, чтобы указать методы доступа и изменения битов флагов состояния. Версия стандарта IEEE 754 2008 года теперь указывает несколько операций для доступа и обработки битов флагов арифметических действий. Модель программирования основана на одном потоке выполнения, и их использование несколькими потоками должно обрабатываться средствами вне стандарта (например, C11 указывает, что флаги имеют локальное хранилище потока ).

IEEE 754 определяет пять арифметических исключений, которые должны быть записаны во флагах состояния («липкие биты»):

Рис. 1: параллельные сопротивления с общим сопротивлением

Возвращаемое значение по умолчанию для каждого исключения предназначено для предоставления правильного результата в большинстве случаев, так что исключения можно игнорировать в большинстве кодов. inexact возвращает правильно округленный результат, а underflow возвращает значение, меньшее или равное наименьшему положительному нормальному числу по величине и почти всегда может быть проигнорировано. [46] delegate-by-zero возвращает бесконечность точно, что обычно затем делит конечное число и, таким образом, дает ноль, или же впоследствии дает недопустимое исключение, если нет, и поэтому также может быть обычно проигнорировано. Например, эффективное сопротивление n резисторов, соединенных параллельно (см. рис. 1), определяется как . Если возникает короткое замыкание с установленным значением 0, вернет +infinity, что даст окончательное значение 0, как и ожидалось [47] (см. пример непрерывной дроби в обосновании конструкции IEEE 754 для другого примера).

Переполнение и недопустимые исключения обычно не могут игнорироваться, но не обязательно представляют собой ошибки: например, процедура поиска корня в рамках своей нормальной работы может оценивать переданную функцию при значениях за пределами ее домена, возвращая NaN и недопустимый флаг исключения, который следует игнорировать до тех пор, пока не будет найдена полезная начальная точка. [46]

Проблемы с точностью

Тот факт, что числа с плавающей точкой не могут точно представлять все действительные числа, и что операции с плавающей точкой не могут точно представлять истинные арифметические операции, приводит ко многим удивительным ситуациям. Это связано с конечной точностью, с которой компьютеры обычно представляют числа.

Например, десятичные числа 0,1 и 0,01 не могут быть представлены точно как двоичные числа с плавающей точкой. В формате IEEE 754 binary32 с его 24-битной мантиссой результат попытки возвести в квадрат приближение к 0,1 не является ни 0,01, ни представимым числом, ближайшим к нему. Десятичное число 0,1 представлено в двоичном виде как e  = −4 ; s  = 110011001100110011001101 , что равно

0,100000001490116119384765625 точно.

Возведение этого числа в квадрат дает

0,010000000298023226097399174250313080847263336181640625 точно.

Возведение в квадрат с округлением до 24-битной точности дает

0,010000000707805156707763671875 точно.

Но представимое число, ближайшее к 0,01, это

0,009999999776482582092285156250 точно.

Кроме того, непредставимость π (и π/2) означает, что попытка вычисления tan(π/2) не даст результата бесконечности, и даже не переполнит обычные форматы с плавающей точкой (предполагая точную реализацию tan). Просто невозможно для стандартного оборудования с плавающей точкой попытаться вычислить tan(π/2), потому что π/2 не может быть представлено точно. Это вычисление на языке C:

/* Достаточно цифр, чтобы убедиться, что мы получаем правильное приближение. */ double pi = 3.1415926535897932384626433832795 ; double z = tan ( pi / 2.0 );      

даст результат 16331239353195370.0. При одинарной точности (с использованием tanfфункции) результат будет −22877332.0.

По той же причине попытка вычисления sin(π) не даст ноль. Результат будет (приблизительно) 0,1225 × 10 −15 в двойной точности или −0,8742 × 10 −7 в одинарной точности. [nb 10]

Хотя сложение и умножение с плавающей точкой являются коммутативными ( a + b = b + a и a × b = b × a ), они не обязательно ассоциативны . То есть, ( a + b ) + c не обязательно равно a + ( b + c ) . Использование 7-значной значащей десятичной арифметики:

а = 1234,567, б = 45,67834, в = 0,0004
(а + б) + в: 1234.567 (а) + 45.67834 (б) ____________ 1280.24534 округляется до 1280.245
 1280,245 (а + б) + 0,0004 (с) ____________ 1280,2454 округляется до 1280,245 ← (a + b) + c
а + (б + в): 45.67834 (б) + 0,0004 (с) ____________ 45.67874
 1234.567 (а) + 45.67874 (б + в) ____________ 1280,24574 округляется до 1280,246 ← a + (b + c)

Они также не обязательно являются дистрибутивными . То есть, ( a + b ) × c может не совпадать с a × c + b × c :

1234,567 × 3,333333 = 4115,223 1,234567 × 3,333333 = 4,115223 4115,223 + 4,115223 = 4119,338 но 1234,567 + 1,234567 = 1235,802 1235,802 × 3,333333 = 4119,340

Помимо потери значимости, невозможности точного представления таких чисел, как π и 0,1, и других незначительных неточностей, могут возникнуть следующие явления:

Инциденты

Точность машины и обратный анализ ошибок

Машинная точность — это величина, характеризующая точность системы с плавающей точкой, и используемая в обратном анализе ошибок алгоритмов с плавающей точкой. Она также известна как округление единиц или машинный эпсилон . Обычно обозначается Ε mach , ее значение зависит от конкретного используемого округления.

С округлением до нуля, тогда как округление до ближайшего, где B — основание системы, а P — точность мантиссы (в основании B ).

Это важно, поскольку ограничивает относительную погрешность представления любого ненулевого действительного числа x в нормализованном диапазоне системы с плавающей точкой:

Анализ обратных ошибок, теория которого была разработана и популяризирована Джеймсом Х. Уилкинсоном , может быть использован для установления того, что алгоритм, реализующий числовую функцию, численно устойчив. [52] Основной подход заключается в том, чтобы показать, что хотя вычисленный результат из-за ошибок округления не будет точно правильным, он является точным решением близлежащей проблемы со слегка возмущенными входными данными. Если требуемое возмущение мало, порядка неопределенности во входных данных, то результаты в некотором смысле настолько точны, насколько «заслуживают» данные. Тогда алгоритм определяется как обратно устойчивый . Устойчивость является мерой чувствительности к ошибкам округления данной числовой процедуры; напротив, число условий функции для данной задачи указывает на присущую функции чувствительность к малым возмущениям во входных данных и не зависит от реализации, используемой для решения проблемы. [53]

В качестве тривиального примера рассмотрим простое выражение, дающее скалярное произведение векторов (длины два) и , тогда и так далее.

где

где

по определению, что является суммой двух слегка возмущенных (порядка Ε mach ) входных данных, и поэтому обратно устойчиво. Для более реалистичных примеров в числовой линейной алгебре см. Higham 2002 [54] и другие ссылки ниже.

Минимизация влияния проблем с точностью

Хотя отдельные арифметические операции IEEE 754 гарантированно точны в пределах половины ULP , более сложные формулы могут страдать от больших ошибок по разным причинам. Потеря точности может быть существенной, если задача или ее данные плохо обусловлены , что означает, что правильный результат сверхчувствителен к крошечным возмущениям в ее данных. Однако даже хорошо обусловленные функции могут страдать от большой потери точности, если используется алгоритм, численно нестабильный для этих данных: внешне эквивалентные формулировки выражений на языке программирования могут заметно отличаться по своей численной устойчивости. Одним из подходов к устранению риска такой потери точности является разработка и анализ численно устойчивых алгоритмов, что является целью раздела математики, известного как численный анализ . Другой подход, который может защитить от риска численной нестабильности, — это вычисление промежуточных (рабочих) значений в алгоритме с более высокой точностью, чем требуется для конечного результата, [55] что может устранить или уменьшить на порядки [56] такой риск: четверная точность и расширенная точность IEEE 754 предназначены для этой цели при вычислениях с двойной точностью. [57] [примечание 11]

Например, следующий алгоритм представляет собой прямую реализацию для вычисления функции A ( x ) = ( x −1) / (exp( x −1) − 1) , которая хорошо обусловлена ​​при 1,0, [примечание 12] однако можно показать, что она численно нестабильна и теряет до половины значащих цифр, переносимых арифметикой, при вычислении вблизи 1,0. [58]

двойной А ( двойной Х )  { двойной Y , Z ; // [1]    Y = X - 1,0 ;     Z = ехр ( Y );   если ( Z != 1.0 )    Z = Y / ( Z - 1,0 ); // [2]        вернуть Z ; }

Однако если все промежуточные вычисления выполняются с повышенной точностью (например, путем установки строки [1] в значение C99 long double ), то можно поддерживать полную точность в конечном результате double. [nb 13] В качестве альтернативы численный анализ алгоритма показывает, что если сделать следующее неочевидное изменение в строке [2]:

Z = log ( Z ) / ( Z - 1,0 );      

тогда алгоритм становится численно устойчивым и может выполнять вычисления с полной двойной точностью.

Для поддержания свойств таких тщательно сконструированных численно устойчивых программ требуется осторожное обращение со стороны компилятора . Определенные «оптимизации», которые могут выполнять компиляторы (например, переупорядочивание операций), могут работать против целей хорошо работающего программного обеспечения. Существуют некоторые разногласия относительно недостатков компиляторов и дизайна языков в этой области: C99 является примером языка, где такие оптимизации тщательно определены для поддержания числовой точности. См. внешние ссылки в конце этой статьи.

Подробное рассмотрение методов написания высококачественного программного обеспечения с плавающей точкой выходит за рамки этой статьи, и читатель может обратиться к [54] [59] и другим ссылкам в конце этой статьи. Кахан предлагает несколько практических правил, которые могут существенно снизить на порядки [59] риск числовых аномалий, в дополнение к или вместо более тщательного численного анализа. К ним относятся: как отмечено выше, вычисление всех выражений и промежуточных результатов с наивысшей точностью, поддерживаемой оборудованием (общее практическое правило заключается в том, чтобы переносить в два раза большую точность желаемого результата, т. е. вычислять с двойной точностью для конечного результата с одинарной точностью или с двойной расширенной или учетверенной точностью для результатов вплоть до двойной точности [60] ); и округление входных данных и результатов только до точности, требуемой и поддерживаемой входными данными (перенос избыточной точности в конечный результат сверх требуемой и поддерживаемой входными данными может вводить в заблуждение, увеличивает стоимость хранения и снижает скорость, а избыточные биты могут повлиять на сходимость числовых процедур: [61] в частности, первая форма итеративного примера, приведенного ниже, сходится правильно при использовании этого эмпирического правила). Далее следуют краткие описания нескольких дополнительных проблем и методов.

Поскольку десятичные дроби часто не могут быть точно представлены в двоичном формате с плавающей точкой, такая арифметика лучше всего подходит, когда она просто используется для измерения реальных величин в широком диапазоне масштабов (например, период обращения луны вокруг Сатурна или масса протона ) , а хуже всего — когда от нее ожидается моделирование взаимодействия величин, выраженных в виде десятичных строк, которые, как ожидается, будут точными. [56] [59] Примером последнего случая являются финансовые расчеты. По этой причине финансовое программное обеспечение, как правило, не использует двоичное представление чисел с плавающей точкой. [62] Тип данных «decimal» языков программирования C# и Python и десятичные форматы стандарта IEEE 754-2008 разработаны для того, чтобы избежать проблем двоичных представлений с плавающей точкой при применении к введенным человеком точным десятичным значениям и заставить арифметику всегда вести себя так, как ожидается, когда числа печатаются в десятичном формате.

Ожидания от математики могут не оправдаться в области вычислений с плавающей точкой. Например, известно, что , и что , однако на эти факты нельзя полагаться, когда задействованные величины являются результатом вычислений с плавающей точкой.

Использование теста на равенство ( if (x==y) ...) требует осторожности при работе с числами с плавающей точкой. Даже простые выражения, такие как 0.6/0.2-3==0will, на большинстве компьютеров не будут истинными [63] (например, в IEEE 754 двойная точность 0.6/0.2 - 3приблизительно равна -4,44089209850063e-16). Следовательно, такие тесты иногда заменяются «нечеткими» сравнениями ( if (abs(x-y) < epsilon) ..., где epsilon достаточно мал и адаптирован к приложению, например, 1,0E−13). Разумность этого действия сильно различается и может потребовать численного анализа для ограничения epsilon. [54] Значения, полученные из первичного представления данных, и их сравнения должны выполняться с более широкой, расширенной точностью, чтобы минимизировать риск таких несоответствий из-за ошибок округления. [59] Часто лучше организовать код таким образом, чтобы такие тесты были ненужными. Например, в вычислительной геометрии точные проверки того, лежит ли точка вне или на линии или плоскости, определяемой другими точками, могут быть выполнены с использованием методов адаптивной точности или точной арифметики. [64]

Небольшие ошибки в арифметике с плавающей точкой могут расти, когда математические алгоритмы выполняют операции огромное количество раз. Несколько примеров — это обращение матрицы , вычисление собственного вектора и решение дифференциальных уравнений. Эти алгоритмы должны быть очень тщательно разработаны, с использованием численных подходов, таких как итеративное уточнение , если они должны работать хорошо. [65]

Суммирование вектора значений с плавающей точкой является базовым алгоритмом в научных вычислениях , поэтому понимание того, когда может произойти потеря значимости, имеет важное значение. Например, если складывается очень большое количество чисел, отдельные слагаемые очень малы по сравнению с суммой. Это может привести к потере значимости. Типичное сложение будет выглядеть примерно так:

3253.671+ 3.141276-----------3256.812

Нижние 3 цифры слагаемых фактически теряются. Предположим, например, что нужно сложить много чисел, все из которых приблизительно равны 3. После сложения 1000 из них текущая сумма составляет около 3000; потерянные цифры не восстанавливаются. Алгоритм суммирования Кахана может быть использован для уменьшения ошибок. [54]

Ошибка округления может повлиять на сходимость и точность итеративных численных процедур. Например, Архимед аппроксимировал π, вычисляя периметры многоугольников, вписывающих и описывающих окружность, начиная с шестиугольников и последовательно удваивая число сторон. Как отмечено выше, вычисления можно перестроить таким образом, чтобы это было математически эквивалентно, но менее подвержено ошибкам ( численный анализ ). Две формы рекуррентной формулы для описанного многоугольника: [ необходима цитата ]

Ниже приведено вычисление с использованием арифметики IEEE «double» (значащая часть с точностью 53 бита):

i 6 × 2 i × t i , первая форма 6 × 2 i × t i , вторая форма-------------------------------------------------- ------- 0 3 .4641016151377543863 3 .4641016151377543863 1 3 .2153903091734710173 3 .2153903091734723496 2 3.1 596599420974940120 3.1 596599420975006733 3 3,14 60862151314012979 3,14 60862151314352708 4 3,14 27145996453136334 3,14 27145996453689225 5 3.141 8730499801259536 3.141 8730499798241950 6 3.141 6627470548084133 3.141 6627470568494473 7 3.141 6101765997805905 3.141 6101766046906629 8 3.14159 70343230776862 3.14159 70343215275928 9 3.14159 37488171150615 3.14159 3748771353666810 3.141592 9278733740748 3.141592 927385097988511 3.141592 7256228504127 3.141592 722038614837712 3.1415926 717412858693 3.1415926 70701999212513 3.1415926 189011456060 3.14159265 7867845472814 3.1415926 717412858693 3.14159265 4659307370915 3.14159 19358822321783 3.141592653 857173011916 3.1415926 717412858693 3.141592653 656639422217 3.1415 810075796233302 3.141592653 606506191318 3.1415926 717412858693 3.1415926535 93972883619 3.141 4061547378810956 3.1415926535 90839390120 3.14 05434924008406305 3.1415926535 90056016821 3.14 00068646912273617 3.141592653589 860839622 3,1 349453756585929919 3.141592653589 812211823 3,14 00068646912273617 3,14159265358979 9555224 3 .2245152435345525443 3.14159265358979 6890725 3.14159265358979 6224626 3.14159265358979 6224627 3.14159265358979 6224628 3.14159265358979 62246 Истинное значение равно 3,14159265358979323846264338327...

Хотя обе формы формулы повторения явно математически эквивалентны, [nb 14] первая вычитает 1 из числа, чрезвычайно близкого к 1, что приводит к все более проблематичной потере значащих цифр . Поскольку повторение применяется повторно, точность сначала улучшается, но затем ухудшается. Она никогда не становится лучше, чем около 8 цифр, хотя 53-битная арифметика должна быть способна к точности около 16 цифр. Когда используется вторая форма формулы повторения, значение сходится к 15 цифрам точности.

Оптимизация «быстрой математики»

Вышеупомянутое отсутствие ассоциативности операций с плавающей точкой в ​​целом означает, что компиляторы не могут так же эффективно переупорядочивать арифметические выражения, как они могли бы с целочисленной и фиксированной арифметикой, что представляет собой препятствие для оптимизаций, таких как устранение общих подвыражений и автовекторизация . [ 66] Опция «быстрой математики» во многих компиляторах (ICC, GCC, Clang, MSVC...) включает повторную ассоциацию вместе с небезопасными предположениями, такими как отсутствие NaN и бесконечных чисел в IEEE 754. Некоторые компиляторы также предлагают более детальные опции, чтобы включить только повторную ассоциацию. В любом случае программист подвергается многим подводным камням точности, упомянутым выше для части программы, использующей «быструю» математику. [67]

В некоторых компиляторах (GCC и Clang) включение «быстрой» математики может привести к отключению программой субнормальных чисел с плавающей точкой при запуске, что повлияет на поведение чисел с плавающей точкой не только сгенерированного кода, но и любой программы, использующей такой код в качестве библиотеки . [68]

В большинстве компиляторов Fortran , как разрешено стандартом ISO/IEC 1539-1:2004 Fortran, повторная ассоциация является значением по умолчанию, а ее разрушение в значительной степени предотвращается настройкой «protect parens» (также включенной по умолчанию). Эта настройка не позволяет компилятору повторно ассоциировать данные за пределами скобок. [69] Компилятор Intel Fortran является заметным исключением. [70]

Распространенной проблемой в «быстрой» математике является то, что подвыражения могут не оптимизироваться одинаково от места к месту, что приводит к неожиданным различиям. Одной из интерпретаций проблемы является то, что «быстрая» математика, как она реализована в настоящее время, имеет плохо определенную семантику. Одна из попыток формализовать «быстрые» математические оптимизации наблюдается в Icing , проверенном компиляторе. [71]

Смотрите также

Примечания

  1. ^ Мантиссу числа с плавающей точкой некоторые авторы также называют мантиссой — не путать с мантиссой логарифма . Некоторые также используют несколько неопределенные термины, такие как коэффициент или аргумент . Использование термина дробь некоторыми авторами также потенциально вводит в заблуждение. Термин характеристика (используемый, например, CDC ) неоднозначен, поскольку исторически он также использовался для указания некоторой формы экспоненты чисел с плавающей точкой .
  2. ^ Экспонента числа с плавающей точкой иногда также называется масштабом . Термин характеристика (для смещенной экспоненты , смещения экспоненты или избыточного представления n ) неоднозначен, так как исторически он также использовался для указания мантиссы чисел с плавающей точкой.
  3. ^ Шестнадцатеричная (основание 16) арифметика с плавающей точкой используется в IBM System 360 (1964) и 370 (1970), а также в различных более новых машинах IBM, в мэйнфреймах серий RCA Spectra 70 (1964), Siemens 4004 (1965), 7.700 (1974), 7.800, 7.500 (1977) и их преемниках, мэйнфреймах серии Unidata 7.000, компьютерах Manchester MU5 (1972), HEP (1982) и в семействах мэйнфреймов, совместимых с 360/370, производимых Fujitsu, Amdahl и Hitachi. Он также используется в Illinois ILLIAC III (1966), Data General Eclipse S/200 (ок. 1974), Gould Powernode 9080 (1980-е), Interdata 8/32 (1970-е), SEL Systems 85 и 86, а также SDS Sigma 5 (1967), 7 (1966) и Xerox Sigma 9 (1970).
  4. ^ Восьмеричная (основание 8) арифметика с плавающей точкой используется в компьютерах Ferranti Atlas (1962), Burroughs B5500 (1964), Burroughs B5700 (1971), Burroughs B6700 (1971) и Burroughs B7700 (1972).
  5. ^ Четвертичная (основание 4) арифметика с плавающей точкой используется в компьютере Illinois ILLIAC II (1962). Она также используется в системах высокоточного обследования местности Digital Field System DFS IV и V.
  6. ^ Арифметика с плавающей точкой Base-256 используется в компьютере R1 Института Райса (с 1958 года).
  7. ^ В компьютере MANIAC II (1956) используется арифметика с плавающей точкой на основе 65536 .
  8. ^ Аппаратное обеспечение компьютера не обязательно вычисляет точное значение; оно просто должно выдать эквивалентный округленный результат, как если бы оно вычислило бесконечно точный результат.
  9. ^ Огромная сложность современных алгоритмов деления однажды привела к известной ошибке. Ранняя версия чипа Intel Pentium поставлялась с инструкцией деления , которая в редких случаях давала слегка неверные результаты. Множество компьютеров было отправлено до того, как была обнаружена ошибка. Пока неисправные компьютеры не были заменены, были разработаны исправленные версии компиляторов, которые могли избежать случаев сбоя. См. ошибку Pentium FDIV .
  10. ^ Но попытка вычисления cos(π) дает −1 точно. Поскольку производная близка к нулю вблизи π, эффект неточности в аргументе намного меньше, чем интервал чисел с плавающей точкой вокруг −1, и округленный результат точен.
  11. ^ Уильям Кахан отмечает: «За исключением крайне редких ситуаций, сверхточная арифметика обычно снижает риски, связанные с округлением, при гораздо меньших затратах, чем стоимость услуг компетентного аналитика ошибок».
  12. ^ Разложение Тейлора этой функции показывает, что она хорошо обусловлена ​​вблизи 1: A(x) = 1 − (x−1)/2 + (x−1)^2/12 − (x−1)^4/720 + (x−1)^6/30240 − (x−1)^8/1209600 + ... для |x−1| < π.
  13. ^ Если long double имеет четверную точность IEEE , то сохраняется полная двойная точность; если long double имеет расширенную двойную точность IEEE , то сохраняется дополнительная, но не полная точность.
  14. ^ Эквивалентность двух форм можно проверить алгебраически, заметив, что знаменатель дроби во второй форме является сопряженным числом числителя первой . Умножая верхнюю и нижнюю части первого выражения на это сопряженное число, получаем второе выражение.

Ссылки

  1. ^ abcdef Мюллер, Жан-Мишель; Бризебар, Николя; де Динешен, Флоран; Жаннерод, Клод-Пьер; Лефевр, Винсент; Мелькионд, Гийом; Револь, Натали ; Стеле, Дэмиен; Торрес, Серж (2010). Справочник по арифметике с плавающей запятой (1-е изд.). Биркхойзер . дои : 10.1007/978-0-8176-4705-6. ISBN 978-0-8176-4704-9. LCCN  2009939668.
  2. ^ ab Sterbenz, Pat H. (1974). Вычисления с плавающей точкой. Englewood Cliffs, NJ, США: Prentice-Hall. ISBN 0-13-322495-3.
  3. ^ Смит, Стивен В. (1997). "Глава 28, Фиксированная и плавающая точка". Руководство ученого и инженера по цифровой обработке сигналов . California Technical Pub. стр. 514. ISBN 978-0-9660176-3-2. Получено 31 декабря 2012 г.
  4. ^ аб Зеенднер, Эберхард (лето 2008 г.). «Rechnerarithmetik: Fest- und Gleitkommasysteme» (PDF) (сценарий лекции) (на немецком языке). Йенский университет имени Фридриха Шиллера . п. 2. Архивировано (PDF) из оригинала 7 августа 2018 г. Проверено 7 августа 2018 г.[1] (Примечание. В этой ссылке неверно указано, что основание числа с плавающей точкой MANIAC II равно 256, тогда как на самом деле оно равно 65536.)
  5. ^ abcd Beebe, Nelson HF (2017-08-22). "Глава H. Исторические архитектуры с плавающей точкой". Справочник по вычислению математических функций - Программирование с использованием библиотеки переносимого программного обеспечения MathCW (1-е изд.). Солт-Лейк-Сити, Юта, США: Springer International Publishing AG . стр. 948. doi :10.1007/978-3-319-64110-2. ISBN 978-3-319-64109-6. LCCN  2017947446. S2CID  30244721.
  6. ^ Savard, John JG (2018) [2007], "The Decimal Floating-Point Standard", quadibloc , заархивировано из оригинала 2018-07-03 , извлечено 2018-07-16
  7. ^ Паркинсон, Роджер (2000-12-07). "Глава 2 - Системы цифровой съемки участка высокого разрешения - Глава 2.1 - Системы цифровой полевой записи". High Resolution Site Surveys (1-е изд.). CRC Press . стр. 24. ISBN 978-0-20318604-6. Получено 18 августа 2019 г. . […] Такие системы, как [Digital Field System] DFS IV и DFS V, были четверичными системами с плавающей запятой и использовали шаг усиления 12 дБ. […](256 страниц)
  8. ^ Lazarus, Roger B. (1957-01-30) [1956-10-01]. "MANIAC II" (PDF) . Лос-Аламос, Нью-Мексико, США: Лос-Аламосская научная лаборатория Калифорнийского университета. стр. 14. LA-2083. Архивировано (PDF) из оригинала 2018-08-07 . Получено 2018-08-07 . […] плавающее основание Maniac, которое равно 2 16 = 65 536. […] Большое основание Maniac позволяет значительно увеличить скорость арифметики с плавающей точкой. Хотя такое большое основание подразумевает возможность до 15 ведущих нулей, большой размер слова в 48 бит гарантирует адекватную значимость. […]
  9. ^ Торрес Кеведо, Леонардо. Automática: Complemento de la Teoría de las Máquinas, (pdf), стр. 575–583, Revista de Obras Públicas, 19 ноября 1914 г.
  10. ^ Рональд Т. Кнойзель. Числа и компьютеры, Springer, стр. 84–85, 2017. ISBN 978-3319505084 
  11. ^ Рэнделл 1982, стр. 6, 11–13.
  12. ^ Рэнделл, Брайан. Цифровые компьютеры, история происхождения, (pdf), стр. 545, Цифровые компьютеры: происхождение, Энциклопедия компьютерных наук, январь 2003 г.
  13. ^ Рохас, Рауль (апрель–июнь 1997 г.). «Наследие Конрада Цузе: архитектура Z1 и Z3» (PDF) . IEEE Annals of the History of Computing . 19 (2): 5–16. doi :10.1109/85.586067. Архивировано (PDF) из оригинала 03.07.2022 . Получено 03.07.2022 .(12 страниц)
  14. ^ Рохас, Рауль (2014-06-07). "Z1: Архитектура и алгоритмы первого компьютера Конрада Цузе". arXiv : 1406.1886 [cs.AR].
  15. ^ ab Kahan, William Morton (1997-07-15). "Пагубное воздействие компьютерных языков и эталонных тестов на прикладную математику, физику и химию. Лекция Джона фон Неймана" (PDF) . стр. 3. Архивировано (PDF) из оригинала 2008-09-05.
  16. ^ Рэнделл, Брайан , ред. (1982) [1973]. Происхождение цифровых компьютеров: избранные статьи (3-е изд.). Берлин; Нью-Йорк: Springer-Verlag . стр. 244. ISBN 978-3-540-11319-5.
  17. Северанс, Чарльз (20.02.1998). «Интервью со стариком плавающей точки».
  18. ^ ISO/IEC 9899:1999 - Языки программирования - C. Iso.org. §F.2, примечание 307.«Расширенный» — это двойной расширенный формат данных IEC 60559. Расширенный относится как к обычному 80-битному, так и к учетверенному 128-битному формату IEC 60559.
  19. ^ "Представление чисел с плавающей точкой IEEE". 2021-08-03.
  20. ^ Использование коллекции компиляторов GNU, параметры i386 и x86-64. Архивировано 16 января 2015 г. на Wayback Machine .
  21. ^ "long double (специфично для GCC) и __float128". StackOverflow .
  22. ^ "Стандарт вызова процедур для 64-битной архитектуры ARM (AArch64)" (PDF) . 2013-05-22. Архивировано (PDF) из оригинала 2013-07-31 . Получено 2019-09-22 .
  23. ^ "ARM Compiler toolchain Compiler Reference, Version 5.03" (PDF) . 2013. Раздел 6.3 Базовые типы данных . Архивировано (PDF) из оригинала 2015-06-27 . Получено 2019-11-08 .
  24. ^ Кахан, Уильям Мортон (2004-11-20). "О стоимости вычислений с плавающей точкой без сверхточной арифметики" (PDF) . Архивировано (PDF) из оригинала 2006-05-25 . Получено 2012-02-19 .
  25. ^ "openEXR". openEXR. Архивировано из оригинала 2013-05-08 . Получено 2012-04-25 . Поскольку спецификация IEEE-754 с плавающей точкой не определяет 16-битный формат, ILM создал формат "half". Значения half имеют 1 бит знака, 5 бит экспоненты и 10 бит мантиссы.
  26. ^ "Техническое введение в OpenEXR – Тип данных half". openEXR . Получено 2024-04-16 .
  27. ^ "Анализ IEEE-754" . Получено 29.08.2024 .
  28. ^ ab Borland staff (1998-07-02) [1994-03-10]. "Преобразование между форматами Microsoft Binary и IEEE". Техническая информационная база данных (TI1431C.txt). Embarcadero USA / Inprise (первоначально: Borland ). Идентификатор 1400. Архивировано из оригинала 20.02.2019 . Получено 30.05.2016 . […] _fmsbintoieee(float *src4, float *dest4) […] Формат MS Binary […] порядок байтов => m3 | m2 | m1 | экспонента […] m1 — старший байт => sbbb|bbbb […] m3 — младший байт […] m = байт мантиссы […] s = знаковый бит […] b = бит […] MBF имеет смещение 128, а IEEE — смещение 127. […] MBF помещает десятичную точку перед предполагаемым битом , тогда как IEEE помещает десятичную точку после предполагаемого бита. […] ieee_exp = msbin[3] - 2; /* на самом деле, msbin[3]-1-128+127 */ […] _dmsbintoieee(double *src8, double *dest8) […] Двоичный формат MS […] порядок байтов => m7 | m6 | m5 | m4 | m3 | m2 | m1 | экспонента […] m1 — старший байт => smmm|mmmm […] m7 — младший байт […] MBF имеет смещение 128, а IEEE — смещение 1023. […] MBF помещает десятичную точку перед предполагаемым битом, тогда как IEEE помещает десятичную точку после предполагаемого бита. […] ieee_exp = msbin[7] - 128 - 1 + 1023; […]
  29. ^ ab Steil, Michael (2008-10-20). "Создайте собственную версию Microsoft BASIC для 6502". pagetable.com. Архивировано из оригинала 2016-05-30 . Получено 2016-05-30 .
  30. ^ "IEEE против Microsoft Binary Format; Rounding Issues (Complete)". Поддержка Microsoft . Microsoft . 2006-11-21. Идентификатор статьи KB35826, Q35826. Архивировано из оригинала 2020-08-28 . Получено 2010-02-24 .
  31. ^ ab Харья, Пареш (2020-05-14). "TensorFloat-32 в графическом процессоре A100 ускоряет обучение ИИ, HPC до 20 раз" . Получено 2020-05-16 .
  32. ^ «Подробный обзор архитектуры NVIDIA Hopper». 2022-03-22.
  33. ^ Мицикявичюс, Паулиус; Стосич, Душан; Берджесс, Нил; Корнеа, Мариус; Дубей, Прадип; Гризентуэйт, Ричард; Ха, Сангвон; Хайнеке, Александр; Джадд, Патрик; Камалу, Джон; Меллемпуди, Навин; Оберман, Стюарт; Шойби, Мохаммад; Сиу, Майкл; Ву, Хао (12.09.2022). «Форматы FP8 для глубокого обучения». arXiv : 2209.05433 [cs.LG].
  34. ^ Кахан, Уильям Мортон (11.01.2006). «Насколько бесполезны бессмысленные оценки округления в вычислениях с плавающей точкой?» (PDF) . Архивировано (PDF) из оригинала 21.12.2004.
  35. ^ ab Gay, David M. (1990). Корректно округленные двоично-десятичные и десятично-двоичные преобразования (технический отчет). NUMERICAL ANALYSIS MANUSCRIPPT 90-10, AT&T BELL LABORATORIES. CiteSeerX 10.1.1.31.4049 . (dtoa.c в netlab)
  36. ^ Лойч, Флориан (2010). «Печать чисел с плавающей точкой быстро и точно с целыми числами» (PDF) . Труды 31-й конференции ACM SIGPLAN по проектированию и реализации языков программирования . PLDI '10: Конференция ACM SIGPLAN по проектированию и реализации языков программирования. стр. 233–243. doi :10.1145/1806596.1806623. ISBN 978-1-45030019-3. S2CID  910409. Архивировано (PDF) из оригинала 29.07.2014.
  37. ^ "Добавлена ​​поддержка алгоритма Grisu3 для double.ToString(). от mazong1123 · Запрос на извлечение № 14646 · dotnet/coreclr". GitHub .
  38. ^ Адамс, Ульф (2018-12-02). «Ryū: быстрое преобразование числа с плавающей точкой в ​​строку». Уведомления ACM SIGPLAN . 53 (4): 270–282. doi : 10.1145/3296979.3192369 . S2CID  218472153.
  39. ^ Джульетти, Рафаэлло. «Способ Schubfach для создания двойников».
  40. ^ "аболз/Дракеннест". Гитхаб . 10.11.2022.
  41. ^ "google/double-conversion". GitHub . 2020-09-21.
  42. ^ Лемир, Дэниел (2021-03-22). «Разбор чисел со скоростью гигабайт в секунду». Программное обеспечение: практика и опыт . 51 (8): 1700–1727. arXiv : 2101.11408 . doi : 10.1002/spe.2984. S2CID  231718830.
  43. ^ abc Goldberg, David (март 1991 г.). «Что каждый специалист по компьютерам должен знать об арифметике с плавающей точкой». ACM Computing Surveys . 23 (1): 5–48. doi : 10.1145/103162.103163 . S2CID  222008826.(С приложением «Различия между реализациями IEEE 754»: [2], [3])
  44. ^ Паттерсон, Дэвид А.; Хеннесси, Джон Л. (2014). Организация и проектирование компьютеров, Интерфейс оборудования/программного обеспечения . Серия Моргана Кауфмана по архитектуре и проектированию компьютеров (5-е изд.). Уолтем, Массачусетс, США: Elsevier. стр. 793. ISBN 978-9-86605267-5.
  45. ^ ab патент США 3037701A, Хуберто М. Сьерра, «Средства арифметического управления с плавающей десятичной точкой для калькулятора», выдан 05.06.1962 
  46. ^ ab Kahan, William Morton (1997-10-01). "Lecture Notes on the Status of IEEE Standard 754 for Binary Floating-Point Arithmetic" (PDF) . стр. 9. Архивировано (PDF) из оригинала 2002-06-22.
  47. ^ "D.3.2.1". Руководства разработчиков программного обеспечения для архитектур Intel 64 и IA-32 . Том 1.
  48. ^ Харрис, Ричард (октябрь 2010 г.). «You're Going To Have To Think!». Перегрузка (99): 5–10. ISSN  1354-3172 . Получено 24.09.2011 . Гораздо более тревожной является ошибка отмены, которая может привести к катастрофической потере точности.[4]
  49. ^ Кристофер Баркер: PEP 485 — Функция для проверки приблизительного равенства
  50. ^ "Противоракетная оборона Patriot, проблема с программным обеспечением привела к отказу системы в Дхархане, Саудовская Аравия". Счетная палата правительства США . Отчет GAO IMTEC 92-26.
  51. Скил, Роберт (июль 1992 г.), «Ошибка округления и ракета Patriot» (PDF) , SIAM News , 25 (4): 11 , получено 15 ноября 2024 г.
  52. ^ Уилкинсон, Джеймс Харди (2003-09-08). «Анализ ошибок». В Ралстоне, Энтони; Рейли, Эдвин Д.; Хеммендингер, Дэвид (ред.). Энциклопедия компьютерных наук. Wiley . С. 669–674. ISBN 978-0-470-86412-8. Получено 14.05.2013 .
  53. ^ Эйнарссон, Бо (2005). Точность и надежность в научных вычислениях. Общество промышленной и прикладной математики (SIAM). стр. 50–. ISBN 978-0-89871-815-7. Получено 14.05.2013 .
  54. ^ abcd Хайэм, Николас Джон (2002). Точность и устойчивость численных алгоритмов (2-е изд.). Общество промышленной и прикладной математики (SIAM). стр. 27–28, 110–123, 493. ISBN 978-0-89871-521-7. 0-89871-355-2.
  55. ^ Оливейра, Сьюли; Стюарт, Дэвид Э. (2006-09-07). Написание научного программного обеспечения: руководство по хорошему стилю. Cambridge University Press . стр. 10–. ISBN 978-1-139-45862-7.
  56. ^ ab Kahan, William Morton (2005-07-15). Арифметика с плавающей точкой осаждена «деловыми решениями» (PDF) . IEEE-спонсируемый ARITH 17 , Симпозиум по компьютерной арифметике (основной доклад). стр. 6, 18. Архивировано (PDF) из оригинала 2006-03-17 . Получено 2013-05-23 .(Примечание. Кахан подсчитал, что частота получения чрезмерно неточных результатов вблизи сингулярностей снижается примерно в 1/2000 раз при использовании 11 дополнительных бит точности двойного расширенного .)
  57. ^ Кахан, Уильям Мортон (2011-08-03). Отчаянно необходимые средства для неотлаживаемости больших вычислений с плавающей точкой в ​​науке и технике (PDF) . Рабочая конференция IFIP/SIAM/NIST по количественной оценке неопределенности в научных вычислениях, Боулдер, Колорадо. стр. 33. Архивировано (PDF) из оригинала 2013-06-20.
  58. ^ Кахан, Уильям Мортон ; Дарси, Джозеф (2001) [1998-03-01]. "Как плавающая точка Java вредит всем и везде" (PDF) . Архивировано (PDF) из оригинала 2000-08-16 . Получено 2003-09-05 .
  59. ^ abcd Кахан, Уильям Мортон (2000-08-27). "Маркетинг против математики" (PDF) . стр. 15, 35, 47. Архивировано (PDF) из оригинала 2003-08-15.
  60. ^ Кахан, Уильям Мортон (1981-02-12). "Зачем нам нужен стандарт арифметики с плавающей точкой?" (PDF) . стр. 26. Архивировано (PDF) из оригинала 2004-12-04.
  61. ^ Кахан, Уильям Мортон (2001-06-04). Биндель, Дэвид (ред.). "Конспект лекций по системной поддержке научных вычислений" (PDF) . Архивировано (PDF) из оригинала 2013-05-17.
  62. ^ "Общая десятичная арифметика". Speleotrove.com . Получено 2012-04-25 .
  63. ^ Кристиансен, Том; Торкингтон, Натан; и др. (2006). "perlfaq4 / Почему int() сломан?". perldoc.perl.org . Получено 11.01.2011 .
  64. ^ Шевчук, Джонатан Ричард (1997). «Адаптивная точность арифметики с плавающей точкой и быстрые надежные геометрические предикаты». Дискретная и вычислительная геометрия . 18 (3): 305–363. doi : 10.1007/PL00009321 .
  65. ^ Кахан, Уильям Мортон ; Айвори, Мелоди И. (1997-07-03). "Скругление ухудшает идеализированную консоль" (PDF) . Архивировано (PDF) из оригинала 2003-12-05.
  66. ^ "Автовекторизация в LLVM". Документация LLVM 13. Мы поддерживаем операции редукции с плавающей точкой при использовании -ffast-math.
  67. ^ "FloatingPointMath". GCC Wiki .
  68. ^ "55522 – -funsafe-math-optimizations неожиданно вреден, особенно с -shared". gcc.gnu.org .
  69. ^ «Параметры генерации кода (компилятор GNU Fortran)». gcc.gnu.org .
  70. ^ "Ошибка в zheevd · Проблема № 43 · Ссылка-LAPACK/lapack". GitHub .
  71. ^ Беккер, Хайко; Дарулова, Ева; Майрин, Магнус О.; Татлок, Захари (2019). Icing: Поддержка оптимизации в стиле быстрой математики в проверенном компиляторе . CAV 2019: Компьютерная верификация. Том 11562. С. 155–173. doi : 10.1007/978-3-030-25543-5_10 .

Дальнейшее чтение

Внешние ссылки