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 ведущий бит 1 нормализованной мантиссы фактически не хранится в данных компьютера. Он называется «скрытым» или «неявным» битом. Из-за этого формат одинарной точности на самом деле имеет мантису с точностью 24 бита, формат двойной точности — 53, а четверной — 113.

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

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

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

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

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

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

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

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

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

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

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

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

где

где

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

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

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

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

двойной А ( двойной Х )  { двойной 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 );      

then the algorithm becomes numerically stable and can compute to full double precision.

To maintain the properties of such carefully constructed numerically stable programs, careful handling by the compiler is required. Certain "optimizations" that compilers might make (for example, reordering operations) can work against the goals of well-behaved software. There is some controversy about the failings of compilers and language designs in this area: C99 is an example of a language where such optimizations are carefully specified to maintain numerical precision. See the external references at the bottom of this article.

A detailed treatment of the techniques for writing high-quality floating-point software is beyond the scope of this article, and the reader is referred to,[53][58] and the other references at the bottom of this article. Kahan suggests several rules of thumb that can substantially decrease by orders of magnitude[58] the risk of numerical anomalies, in addition to, or in lieu of, a more careful numerical analysis. These include: as noted above, computing all expressions and intermediate results in the highest precision supported in hardware (a common rule of thumb is to carry twice the precision of the desired result, i.e. compute in double precision for a final single-precision result, or in double extended or quad precision for up to double-precision results[59]); and rounding input data and results to only the precision required and supported by the input data (carrying excess precision in the final result beyond that required and supported by the input data can be misleading, increases storage cost and decreases speed, and the excess bits can affect convergence of numerical procedures:[60] notably, the first form of the iterative example given below converges correctly when using this rule of thumb). Brief descriptions of several additional issues and techniques follow.

As decimal fractions can often not be exactly represented in binary floating-point, such arithmetic is at its best when it is simply being used to measure real-world quantities over a wide range of scales (such as the orbital period of a moon around Saturn or the mass of a proton), and at its worst when it is expected to model the interactions of quantities expressed as decimal strings that are expected to be exact.[55][58] An example of the latter case is financial calculations. For this reason, financial software tends not to use a binary floating-point number representation.[61] The "decimal" data type of the C# and Python programming languages, and the decimal formats of the IEEE 754-2008 standard, are designed to avoid the problems of binary floating-point representations when applied to human-entered exact decimal values, and make the arithmetic always behave as expected when numbers are printed in decimal.

Expectations from mathematics may not be realized in the field of floating-point computation. For example, it is known that , and that , however these facts cannot be relied on when the quantities involved are the result of floating-point computation.

The use of the equality test (if (x==y) ...) requires care when dealing with floating-point numbers. Even simple expressions like 0.6/0.2-3==0 will, on most computers, fail to be true[62] (in IEEE 754 double precision, for example, 0.6/0.2 - 3 is approximately equal to -4.44089209850063e-16). Consequently, such tests are sometimes replaced with "fuzzy" comparisons (if (abs(x-y) < epsilon) ..., where epsilon is sufficiently small and tailored to the application, such as 1.0E−13). The wisdom of doing this varies greatly, and can require numerical analysis to bound epsilon.[53] Values derived from the primary data representation and their comparisons should be performed in a wider, extended, precision to minimize the risk of such inconsistencies due to round-off errors.[58] It is often better to organize the code in such a way that such tests are unnecessary. For example, in computational geometry, exact tests of whether a point lies off or on a line or plane defined by other points can be performed using adaptive precision or exact arithmetic methods.[63]

Small errors in floating-point arithmetic can grow when mathematical algorithms perform operations an enormous number of times. A few examples are matrix inversion, eigenvector computation, and differential equation solving. These algorithms must be very carefully designed, using numerical approaches such as iterative refinement, if they are to work well.[64]

Summation of a vector of floating-point values is a basic algorithm in scientific computing, and so an awareness of when loss of significance can occur is essential. For example, if one is adding a very large number of numbers, the individual addends are very small compared with the sum. This can lead to loss of significance. A typical addition would then be something like

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

The low 3 digits of the addends are effectively lost. Suppose, for example, that one needs to add many numbers, all approximately equal to 3. After 1000 of them have been added, the running sum is about 3000; the lost digits are not regained. The Kahan summation algorithm may be used to reduce the errors.[53]

Round-off error can affect the convergence and accuracy of iterative numerical procedures. As an example, Archimedes approximated π by calculating the perimeters of polygons inscribing and circumscribing a circle, starting with hexagons, and successively doubling the number of sides. As noted above, computations may be rearranged in a way that is mathematically equivalent but less prone to error (numerical analysis). Two forms of the recurrence formula for the circumscribed polygon are:[citation needed]

Here is a computation using IEEE "double" (a significand with 53 bits of precision) arithmetic:

 i 6 × 2i × ti, first form 6 × 2i × ti, second form--------------------------------------------------------- 0 3.4641016151377543863 3.4641016151377543863 1 3.2153903091734710173 3.2153903091734723496 2 3.1596599420974940120 3.1596599420975006733 3 3.1460862151314012979 3.1460862151314352708 4 3.1427145996453136334 3.1427145996453689225 5 3.1418730499801259536 3.1418730499798241950 6 3.1416627470548084133 3.1416627470568494473 7 3.1416101765997805905 3.1416101766046906629 8 3.1415970343230776862 3.1415970343215275928 9 3.1415937488171150615 3.141593748771353666810 3.1415929278733740748 3.141592927385097988511 3.1415927256228504127 3.141592722038614837712 3.1415926717412858693 3.141592670701999212513 3.1415926189011456060 3.141592657867845472814 3.1415926717412858693 3.141592654659307370915 3.1415919358822321783 3.141592653857173011916 3.1415926717412858693 3.141592653656639422217 3.1415810075796233302 3.141592653606506191318 3.1415926717412858693 3.141592653593972883619 3.1414061547378810956 3.141592653590839390120 3.1405434924008406305 3.141592653590056016821 3.1400068646912273617 3.141592653589860839622 3.1349453756585929919 3.141592653589812211823 3.1400068646912273617 3.141592653589799555224 3.2245152435345525443 3.141592653589796890725 3.141592653589796224626 3.141592653589796224627 3.141592653589796224628 3.1415926535897962246 The true value is 3.14159265358979323846264338327...

While the two forms of the recurrence formula are clearly mathematically equivalent,[nb 14] the first subtracts 1 from a number extremely close to 1, leading to an increasingly problematic loss of significant digits. As the recurrence is applied repeatedly, the accuracy improves at first, but then it deteriorates. It never gets better than about 8 digits, even though 53-bit arithmetic should be capable of about 16 digits of precision. When the second form of the recurrence is used, the value converges to 15 digits of precision.

"Fast math" optimization

The aforementioned lack of associativity of floating-point operations in general means that compilers cannot as effectively reorder arithmetic expressions as they could with integer and fixed-point arithmetic, presenting a roadblock in optimizations such as common subexpression elimination and auto-vectorization.[65] The "fast math" option on many compilers (ICC, GCC, Clang, MSVC...) turns on reassociation along with unsafe assumptions such as a lack of NaN and infinite numbers in IEEE 754. Some compilers also offer more granular options to only turn on reassociation. In either case, the programmer is exposed to many of the precision pitfalls mentioned above for the portion of the program using "fast" math.[66]

In some compilers (GCC and Clang), turning on "fast" math may cause the program to disable subnormal floats at startup, affecting the floating-point behavior of not only the generated code, but also any program using such code as a library.[67]

In most Fortran compilers, as allowed by the ISO/IEC 1539-1:2004 Fortran standard, reassociation is the default, with breakage largely prevented by the "protect parens" setting (also on by default). This setting stops the compiler from reassociating beyond the boundaries of parentheses.[68] Intel Fortran Compiler is a notable outlier.[69]

A common problem in "fast" math is that subexpressions may not be optimized identically from place to place, leading to unexpected differences. One interpretation of the issue is that "fast" math as implemented currently has a poorly defined semantics. One attempt at formalizing "fast" math optimizations is seen in Icing, a verified compiler.[70]

See also

Notes

  1. ^ The significand of a floating-point number is also called mantissa by some authors—not to be confused with the mantissa of a logarithm. Somewhat vague, terms such as coefficient or argument are also used by some. The usage of the term fraction by some authors is potentially misleading as well. The term characteristic (as used e.g. by CDC) is ambiguous, as it was historically also used to specify some form of exponent of floating-point numbers.
  2. ^ The exponent of a floating-point number is sometimes also referred to as scale. The term characteristic (for biased exponent, exponent bias, or excess n representation) is ambiguous, as it was historically also used to specify the significand of floating-point numbers.
  3. ^ Hexadecimal (base-16) floating-point arithmetic is used in the IBM System 360 (1964) and 370 (1970) as well as various newer IBM machines, in the RCA Spectra 70 (1964), the Siemens 4004 (1965), 7.700 (1974), 7.800, 7.500 (1977) series mainframes and successors, the Unidata 7.000 series mainframes, the Manchester MU5 (1972), the HEP (1982) computers, and in 360/370-compatible mainframe families made by Fujitsu, Amdahl and Hitachi. It is also used in the Illinois ILLIAC III (1966), Data General Eclipse S/200 (ca. 1974), Gould Powernode 9080 (1980s), Interdata 8/32 (1970s), the SEL Systems 85 and 86 as well as the SDS Sigma 5 (1967), 7 (1966) and Xerox Sigma 9 (1970).
  4. ^ Octal (base-8) floating-point arithmetic is used in the Ferranti Atlas (1962), Burroughs B5500 (1964), Burroughs B5700 (1971), Burroughs B6700 (1971) and Burroughs B7700 (1972) computers.
  5. ^ Quaternary (base-4) floating-point arithmetic is used in the Illinois ILLIAC II (1962) computer. It is also used in the Digital Field System DFS IV and V high-resolution site survey systems.
  6. ^ Base-256 floating-point arithmetic is used in the Rice Institute R1 computer (since 1958).
  7. ^ Base-65536 floating-point arithmetic is used in the MANIAC II (1956) computer.
  8. ^ Computer hardware does not necessarily compute the exact value; it simply has to produce the equivalent rounded result as though it had computed the infinitely precise result.
  9. ^ The enormous complexity of modern division algorithms once led to a famous error. An early version of the Intel Pentium chip was shipped with a division instruction that, on rare occasions, gave slightly incorrect results. Many computers had been shipped before the error was discovered. Until the defective computers were replaced, patched versions of compilers were developed that could avoid the failing cases. See Pentium FDIV bug.
  10. ^ But an attempted computation of cos(π) yields −1 exactly. Since the derivative is nearly zero near π, the effect of the inaccuracy in the argument is far smaller than the spacing of the floating-point numbers around −1, and the rounded result is exact.
  11. ^ William Kahan notes: "Except in extremely uncommon situations, extra-precise arithmetic generally attenuates risks due to roundoff at far less cost than the price of a competent error-analyst."
  12. ^ The Taylor expansion of this function demonstrates that it is well-conditioned near 1: A(x) = 1 − (x−1)/2 + (x−1)^2/12 − (x−1)^4/720 + (x−1)^6/30240 − (x−1)^8/1209600 + ... for |x−1| < π.
  13. ^ If long double is IEEE quad precision then full double precision is retained; if long double is IEEE double extended precision then additional, but not full precision is retained.
  14. ^ The equivalence of the two forms can be verified algebraically by noting that the denominator of the fraction in the second form is the conjugate of the numerator of the first. By multiplying the top and bottom of the first expression by this conjugate, one obtains the second expression.

References

  1. ^ a b c d e f Muller, Jean-Michel; Brisebarre, Nicolas; de Dinechin, Florent; Jeannerod, Claude-Pierre; Lefèvre, Vincent; Melquiond, Guillaume; Revol, Nathalie; Stehlé, Damien; Torres, Serge (2010). Handbook of Floating-Point Arithmetic (1st ed.). Birkhäuser. doi:10.1007/978-0-8176-4705-6. ISBN 978-0-8176-4704-9. LCCN 2009939668.
  2. ^ a b Sterbenz, Pat H. (1974). Floating-Point Computation. Englewood Cliffs, NJ, United States: Prentice-Hall. ISBN 0-13-322495-3.
  3. ^ Smith, Steven W. (1997). "Chapter 28, Fixed versus Floating Point". The Scientist and Engineer's Guide to Digital Signal Processing. California Technical Pub. p. 514. ISBN 978-0-9660176-3-2. Retrieved 2012-12-31.
  4. ^ a b Zehendner, Eberhard (Summer 2008). "Rechnerarithmetik: Fest- und Gleitkommasysteme" (PDF) (Lecture script) (in German). Friedrich-Schiller-Universität Jena. p. 2. Archived (PDF) from the original on 2018-08-07. Retrieved 2018-08-07. [1] (NB. This reference incorrectly gives the MANIAC II's floating point base as 256, whereas it actually is 65536.)
  5. ^ a b c d Beebe, Nelson H. F. (2017-08-22). "Chapter H. Historical floating-point architectures". The Mathematical-Function Computation Handbook - Programming Using the MathCW Portable Software Library (1st ed.). Salt Lake City, UT, USA: Springer International Publishing AG. p. 948. doi:10.1007/978-3-319-64110-2. ISBN 978-3-319-64109-6. LCCN 2017947446. S2CID 30244721.
  6. ^ Savard, John J. G. (2018) [2007], "The Decimal Floating-Point Standard", quadibloc, archived from the original on 2018-07-03, retrieved 2018-07-16
  7. ^ Parkinson, Roger (2000-12-07). "Chapter 2 - High resolution digital site survey systems - Chapter 2.1 - Digital field recording systems". High Resolution Site Surveys (1st ed.). CRC Press. p. 24. ISBN 978-0-20318604-6. Retrieved 2019-08-18. […] Systems such as the [Digital Field System] DFS IV and DFS V were quaternary floating-point systems and used gain steps of 12 dB. […] (256 pages)
  8. ^ Lazarus, Roger B. (1957-01-30) [1956-10-01]. "MANIAC II" (PDF). Los Alamos, NM, USA: Los Alamos Scientific Laboratory of the University of California. p. 14. LA-2083. Archived (PDF) from the original on 2018-08-07. Retrieved 2018-08-07. […] the Maniac's floating base, which is 216 = 65,536. […] The Maniac's large base permits a considerable increase in the speed of floating point arithmetic. Although such a large base implies the possibility of as many as 15 lead zeros, the large word size of 48 bits guarantees adequate significance. […]
  9. ^ Torres Quevedo, Leonardo. Automática: Complemento de la Teoría de las Máquinas, (pdf), pp. 575–583, Revista de Obras Públicas, 19 November 1914.
  10. ^ Ronald T. Kneusel. Numbers and Computers, Springer, pp. 84–85, 2017. ISBN 978-3319505084
  11. ^ Randell 1982, pp. 6, 11–13.
  12. ^ Randell, Brian. Digital Computers, History of Origins, (pdf), p. 545, Digital Computers: Origins, Encyclopedia of Computer Science, January 2003.
  13. ^ Rojas, Raúl (April–June 1997). "Konrad Zuse's Legacy: The Architecture of the Z1 and Z3" (PDF). IEEE Annals of the History of Computing. 19 (2): 5–16. doi:10.1109/85.586067. Archived (PDF) from the original on 2022-07-03. Retrieved 2022-07-03. (12 pages)
  14. ^ Rojas, Raúl (2014-06-07). "The Z1: Architecture and Algorithms of Konrad Zuse's First Computer". arXiv:1406.1886 [cs.AR].
  15. ^ a b Kahan, William Morton (1997-07-15). "The Baleful Effect of Computer Languages and Benchmarks upon Applied Mathematics, Physics and Chemistry. John von Neumann Lecture" (PDF). p. 3. Archived (PDF) from the original on 2008-09-05.
  16. ^ Randell, Brian, ed. (1982) [1973]. The Origins of Digital Computers: Selected Papers (3rd ed.). Berlin; New York: Springer-Verlag. p. 244. ISBN 978-3-540-11319-5.
  17. ^ Severance, Charles (1998-02-20). "An Interview with the Old Man of Floating-Point".
  18. ^ ISO/IEC 9899:1999 - Programming languages - C. Iso.org. §F.2, note 307. "Extended" is IEC 60559's double-extended data format. Extended refers to both the common 80-bit and quadruple 128-bit IEC 60559 formats.
  19. ^ "IEEE Floating-Point Representation". 2021-08-03.
  20. ^ Using the GNU Compiler Collection, i386 and x86-64 Options Archived 2015-01-16 at the Wayback Machine.
  21. ^ "long double (GCC specific) and __float128". StackOverflow.
  22. ^ "Procedure Call Standard for the ARM 64-bit Architecture (AArch64)" (PDF). 2013-05-22. Archived (PDF) from the original on 2013-07-31. Retrieved 2019-09-22.
  23. ^ "ARM Compiler toolchain Compiler Reference, Version 5.03" (PDF). 2013. Section 6.3 Basic data types. Archived (PDF) from the original on 2015-06-27. Retrieved 2019-11-08.
  24. ^ Kahan, William Morton (2004-11-20). "On the Cost of Floating-Point Computation Without Extra-Precise Arithmetic" (PDF). Archived (PDF) from the original on 2006-05-25. Retrieved 2012-02-19.
  25. ^ "openEXR". openEXR. Archived from the original on 2013-05-08. Retrieved 2012-04-25. Since the IEEE-754 floating-point specification does not define a 16-bit format, ILM created the "half" format. Half values have 1 sign bit, 5 exponent bits, and 10 mantissa bits.
  26. ^ "Technical Introduction to OpenEXR – The half Data Type". openEXR. Retrieved 2024-04-16.
  27. ^ "IEEE-754 Analysis". Retrieved 2024-08-29.
  28. ^ a b Borland staff (1998-07-02) [1994-03-10]. "Converting between Microsoft Binary and IEEE formats". Technical Information Database (TI1431C.txt). Embarcadero USA / Inprise (originally: Borland). ID 1400. Archived from the original on 2019-02-20. Retrieved 2016-05-30. […] _fmsbintoieee(float *src4, float *dest4) […] MS Binary Format […] byte order => m3 | m2 | m1 | exponent […] m1 is most significant byte => sbbb|bbbb […] m3 is the least significant byte […] m = mantissa byte […] s = sign bit […] b = bit […] MBF is bias 128 and IEEE is bias 127. […] MBF places the decimal point before the assumed bit, while IEEE places the decimal point after the assumed bit. […] ieee_exp = msbin[3] - 2; /* actually, msbin[3]-1-128+127 */ […] _dmsbintoieee(double *src8, double *dest8) […] MS Binary Format […] byte order => m7 | m6 | m5 | m4 | m3 | m2 | m1 | exponent […] m1 is most significant byte => smmm|mmmm […] m7 is the least significant byte […] MBF is bias 128 and IEEE is bias 1023. […] MBF places the decimal point before the assumed bit, while IEEE places the decimal point after the assumed bit. […] ieee_exp = msbin[7] - 128 - 1 + 1023; […]
  29. ^ a b Steil, Michael (2008-10-20). "Create your own Version of Microsoft BASIC for 6502". pagetable.com. Archived from the original on 2016-05-30. Retrieved 2016-05-30.
  30. ^ "IEEE vs. Microsoft Binary Format; Rounding Issues (Complete)". Microsoft Support. Microsoft. 2006-11-21. Article ID KB35826, Q35826. Archived from the original on 2020-08-28. Retrieved 2010-02-24.
  31. ^ a b Kharya, Paresh (2020-05-14). "TensorFloat-32 in the A100 GPU Accelerates AI Training, HPC up to 20x". Retrieved 2020-05-16.
  32. ^ "NVIDIA Hopper Architecture In-Depth". 2022-03-22.
  33. ^ Micikevicius, Paulius; Stosic, Dusan; Burgess, Neil; Cornea, Marius; Dubey, Pradeep; Grisenthwaite, Richard; Ha, Sangwon; Heinecke, Alexander; Judd, Patrick; Kamalu, John; Mellempudi, Naveen; Oberman, Stuart; Shoeybi, Mohammad; Siu, Michael; Wu, Hao (2022-09-12). "FP8 Formats for Deep Learning". arXiv:2209.05433 [cs.LG].
  34. ^ Kahan, William Morton (2006-01-11). "How Futile are Mindless Assessments of Roundoff in Floating-Point Computation?" (PDF). Archived (PDF) from the original on 2004-12-21.
  35. ^ a b Gay, David M. (1990). Correctly Rounded Binary-Decimal and Decimal-Binary Conversions (Technical report). NUMERICAL ANALYSIS MANUSCRIPT 90-10, AT&T BELL LABORATORIES. CiteSeerX 10.1.1.31.4049. (dtoa.c in netlab)
  36. ^ Loitsch, Florian (2010). "Printing floating-point numbers quickly and accurately with integers" (PDF). Proceedings of the 31st ACM SIGPLAN Conference on Programming Language Design and Implementation. PLDI '10: ACM SIGPLAN Conference on Programming Language Design and Implementation. pp. 233–243. doi:10.1145/1806596.1806623. ISBN 978-1-45030019-3. S2CID 910409. Archived (PDF) from the original on 2014-07-29.
  37. ^ "Added Grisu3 algorithm support for double.ToString(). by mazong1123 · Pull Request #14646 · dotnet/coreclr". GitHub.
  38. ^ Adams, Ulf (2018-12-02). "Ryū: fast float-to-string conversion". ACM SIGPLAN Notices. 53 (4): 270–282. doi:10.1145/3296979.3192369. S2CID 218472153.
  39. ^ Giulietti, Rafaello. "The Schubfach way to render doubles".
  40. ^ "abolz/Drachennest". GitHub. 2022-11-10.
  41. ^ "google/double-conversion". GitHub. 2020-09-21.
  42. ^ Lemire, Daniel (2021-03-22). "Number parsing at a gigabyte per second". Software: Practice and Experience. 51 (8): 1700–1727. arXiv:2101.11408. doi:10.1002/spe.2984. S2CID 231718830.
  43. ^ a b c Goldberg, David (March 1991). "What Every Computer Scientist Should Know About Floating-Point Arithmetic". ACM Computing Surveys. 23 (1): 5–48. doi:10.1145/103162.103163. S2CID 222008826. (With the addendum "Differences Among IEEE 754 Implementations": [2], [3])
  44. ^ Patterson, David A.; Hennessy, John L. (2014). Computer Organization and Design, The Hardware/Software Interface. The Morgan Kaufmann series in computer architecture and design (5th ed.). Waltham, Massachusetts, USA: Elsevier. p. 793. ISBN 978-9-86605267-5.
  45. ^ a b US patent 3037701A, Huberto M Sierra, "Floating decimal point arithmetic control means for calculator", issued 1962-06-05 
  46. ^ a b Kahan, William Morton (1997-10-01). "Lecture Notes on the Status of IEEE Standard 754 for Binary Floating-Point Arithmetic" (PDF). p. 9. Archived (PDF) from the original on 2002-06-22.
  47. ^ "D.3.2.1". Intel 64 and IA-32 Architectures Software Developers' Manuals. Vol. 1.
  48. ^ Harris, Richard (October 2010). "You're Going To Have To Think!". Overload (99): 5–10. ISSN 1354-3172. Retrieved 2011-09-24. Far more worrying is cancellation error which can yield catastrophic loss of precision. [4]
  49. ^ Christopher Barker: PEP 485 -- A Function for testing approximate equality
  50. ^ "Patriot missile defense, Software problem led to system failure at Dharhan, Saudi Arabia". US Government Accounting Office. GAO report IMTEC 92-26.
  51. ^ Wilkinson, James Hardy (2003-09-08). "Error Analysis". In Ralston, Anthony; Reilly, Edwin D.; Hemmendinger, David (eds.). Encyclopedia of Computer Science. Wiley. pp. 669–674. ISBN 978-0-470-86412-8. Retrieved 2013-05-14.
  52. ^ Einarsson, Bo (2005). Accuracy and reliability in scientific computing. Society for Industrial and Applied Mathematics (SIAM). pp. 50–. ISBN 978-0-89871-815-7. Retrieved 2013-05-14.
  53. ^ a b c d Higham, Nicholas John (2002). Accuracy and Stability of Numerical Algorithms (2nd ed.). Society for Industrial and Applied Mathematics (SIAM). pp. 27–28, 110–123, 493. ISBN 978-0-89871-521-7. 0-89871-355-2.
  54. ^ Oliveira, Suely; Stewart, David E. (2006-09-07). Writing Scientific Software: A Guide to Good Style. Cambridge University Press. pp. 10–. ISBN 978-1-139-45862-7.
  55. ^ a b Kahan, William Morton (2005-07-15). Floating-Point Arithmetic Besieged by "Business Decisions" (PDF). IEEE-sponsored ARITH 17, Symposium on Computer Arithmetic (Keynote Address). pp. 6, 18. Archived (PDF) from the original on 2006-03-17. Retrieved 2013-05-23. (NB. Kahan estimates that the incidence of excessively inaccurate results near singularities is reduced by a factor of approx. 1/2000 using the 11 extra bits of precision of double extended.)
  56. ^ Kahan, William Morton (2011-08-03). Desperately Needed Remedies for the Undebuggability of Large Floating-Point Computations in Science and Engineering (PDF). IFIP/SIAM/NIST Working Conference on Uncertainty Quantification in Scientific Computing, Boulder, CO. p. 33. Archived (PDF) from the original on 2013-06-20.
  57. ^ Kahan, William Morton; Darcy, Joseph (2001) [1998-03-01]. "How Java's floating-point hurts everyone everywhere" (PDF). Archived (PDF) from the original on 2000-08-16. Retrieved 2003-09-05.
  58. ^ a b c d Kahan, William Morton (2000-08-27). "Marketing versus Mathematics" (PDF). pp. 15, 35, 47. Archived (PDF) from the original on 2003-08-15.
  59. ^ Kahan, William Morton (1981-02-12). "Why do we need a floating-point arithmetic standard?" (PDF). p. 26. Archived (PDF) from the original on 2004-12-04.
  60. ^ Kahan, William Morton (2001-06-04). Bindel, David (ed.). "Lecture notes of System Support for Scientific Computation" (PDF). Archived (PDF) from the original on 2013-05-17.
  61. ^ "General Decimal Arithmetic". Speleotrove.com. Retrieved 2012-04-25.
  62. ^ Christiansen, Tom; Torkington, Nathan; et al. (2006). "perlfaq4 / Why is int() broken?". perldoc.perl.org. Retrieved 2011-01-11.
  63. ^ Shewchuk, Jonathan Richard (1997). "Adaptive Precision Floating-Point Arithmetic and Fast Robust Geometric Predicates". Discrete & Computational Geometry. 18 (3): 305–363. doi:10.1007/PL00009321.
  64. ^ Kahan, William Morton; Ivory, Melody Y. (1997-07-03). "Roundoff Degrades an Idealized Cantilever" (PDF). Archived (PDF) from the original on 2003-12-05.
  65. ^ "Auto-Vectorization in LLVM". LLVM 13 documentation. We support floating point reduction operations when -ffast-math is used.
  66. ^ "FloatingPointMath". GCC Wiki.
  67. ^ "55522 – -funsafe-math-optimizations is unexpectedly harmful, especially w/ -shared". gcc.gnu.org.
  68. ^ "Code Gen Options (The GNU Fortran Compiler)". gcc.gnu.org.
  69. ^ "Bug in zheevd · Issue #43 · Reference-LAPACK/lapack". GitHub.
  70. ^ Becker, Heiko; Darulova, Eva; Myreen, Magnus O.; Tatlock, Zachary (2019). Icing: Supporting Fast-Math Style Optimizations in a Verified Compiler. CAV 2019: Computer Aided Verification. Vol. 11562. pp. 155–173. doi:10.1007/978-3-030-25543-5_10.

Further reading

External links