Что такое ieee 754

Что такое ieee 754

Дата публикации статьи: 25.04.2009 14:19

Автор: Яшкардин Владимир Леонидович
Сайт: www.softelectro.ru

Данный стандарт разработан ассоциацией IEEE (Institute of Electrical and Electronics Engineers) и используется для представления действительных чисел (чисел с плавающей точкой) в двоичном коде. Наиболее используемый стандарт для вычислений с плавающей точкой, используется многими микропроцессорами и логическими устройствами, а также программными средствами.

В августе 2008 года ассоциация IEEE выпустила стандарт IEEE 754-2008, который включил в себя стандарт IEEE 754-1985.

Описание стандарта.

Основное применение в технике и программирование получили форматы 32 и 64 бита. Например в основных логических языках VB и С используют типы данных single и double. Далее я буду рассказывать в основном про формат single, так как double является просто увеличенной копией single.

Основные понятия в представлении чисел с плавающей точкой.

Возьмем, к примеру, десятичное число 155.625
Представим это число в нормализованном экспоненциальном виде : 1.55625*10^2 =1,55625e+2
Число 1,55625e+2 состоит из двух частей: мантиссы M=1.55625 и экспоненты e =+2
Если мантисса находится в диапазоне 1 В результате мы получим число 155.625 в 32- битном формате IEEE754:1 бит8 бит23 бит32 бит01000 0110001 1011 1010 0000 0000 0000= 43 1B A0 00 (hex)0(dec)134(dec)1810432(dec)знак числа +смещенная экспонентаостаток от мантиссычисло 155.625 в формате IEEE754

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

Приведу формулу для восстановления числа из стандарта IEEE754 для одинарной точности (single):

Проверяем:
F =(-1)^0*2^(134-127)*(1+ 1810432/8388608)= 2^7*(1+0,2158203125)=128*1,2158203125=155.625

Формальное представление нормализованных чисел в формате IEEE 754.

Рис. 1 Представление формата числа в стандарте IEEE 754

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

Рис.2 Формат числа одинарной точности (single-precision) 32 бита

Рис.3 Формат числа двойной точности (double-precision) 64 бита

Исключения чисел формата IEEE754 из алгоритма вычисления по формуле №1.

Отсюда видно, что невозможно представить число нуль в заданном формате.

Поэтому из стандарта сделаны исключения и формула №1 не применяется в следующих случаях:

1. число IEEE754=00 00 00 00hex считается числом +0
Рис.4

2. число IEEE754=7F 80 00 00hex считается числом +∞
Рис.6

3. числа IEEE754=FF (1xxx)X XX XXhex не считается числами (NAN), кроме случая п.2
числа IEEE754=7F (1xxx)X XX XXhex не считается числами (NAN), кроме случая п.2
Рис.8
Число представленное в битах с 0. 22 могут быть любым числом кроме 0.

Формула расчета денормализованных чисел:


Представим полный диапазон чисел представленных в формате 32 бит по стандарту IEEE754:

Рис.14 Диапазон чисел формата 32 бита представленных по стандарту IEEE 754

Заключение.

Стандарт IEEE 754 широко применяется в технике и программировании. При этом хочется отметить, что в нем заложены существенные недостатки. Создается впечатление, что в разработке стандарта не принимали участие профессиональные математики. Директор института математики и ее применений в Миннеаполисе, США Дуглас Н.Арнольд утверждает, что целый ряд крупнейших аварий с человеческими жертвами и миллиардными убытками всецело обязан нынешней технологии компьютерных вычислений и представлений данных по стандарту IEEE 754.

Вы можете прочитать об этом в статье IEEE754-тика угрожает человечеству

Как программист скажу, никогда не применяйте одинарную точность (single) в программах, если полностью не представляете и не контролируете всю процедуру расчета, так как результат компьютерного расчета может быть не предсказуем. На одной из крупных научных конференций ректор Технического университета Вены проф. П. Скалички заявил, что «с тех пор, как подробнее узнал о принятых способах выполнения машинных вычислений, очень опасается ходить по мостам и оказываться внутри других сложных инженерных сооружений».

Формат чисел IEEE754 неплохо работает в технике, когда нужно представить и передать число, но требует абсолютного контроля в операциях деления и умножения.

Вот пример, который вы можете испытать:
Программный код в VB который делит два одинаковых числа 0,3 : 0,3 = 1 (это должно получится)

Private Sub Command1_Click()
Dim a, c As Single
a = 0.3
c = 0.3
Text1.Text = c / a
Text2.Text = a / c
End Sub

Рис.15 Вот результат вычислений этой программы:

a=0.3 c=0.3 c : a = 1.00000003973643
a=0.3 c=0.3 a : c = 0.999999960263572
Здесь вы видите не только не точный результат, но и зависимость результата от расположения переменных. Это только одна операция, представьте, что операций тысячи. Результат таких вычислений будет не предсказуем.

Источник

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

Значения хранятся в следующем виде:

ЗначениеХранение
одиночная точностьразряд знака, 8 разрядов показателя степени, 23 разряда значащей части
двойная точностьразряд знака, 11 разрядов показателя степени, 52 разряда значащей части

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

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

Смещение показателя степени определяется следующим образом:

Показатель степениВеличина смещения
8 разрядов (одиночная точность)127
11 разрядов (двойная точность)1023

Эти экспоненты определяют показатели степени для двойки, а не для десятки. Таким образом, для 8-разрядного формата фактические показатели степени в диапазоне от –127 до 127 хранятся в памяти соответственно в виде значений в диапазоне от 0 до 254. Значение 2 127 примерно равно 10 38 и определяет фактический предел для чисел с одиночной точностью.

Значащая часть хранится в виде двоичной части в форме 1.XXX. Эта часть имеет значение больше 1 и меньше 2. Вещественные числа всегда хранятся в нормализованном представлении. В частности, значение значащей части всегда смещается влево, чтобы ее старший бит имел значение 1. Так как этот разряд всегда равен 1, для форматов одиночной и двойной точности его значение принимается по умолчанию и не хранится в памяти. Двоичная (не десятичная) точка располагается непосредственно справа от начальной 1.

Формат представления с плавающей запятой выглядит следующим образом:

Форматбайт 1байт 2байт 3байт 4.байт n
одиночная точностьSXXXXXXXXMMMMMMMMMMMMMMMMMMMMMMM
двойная точностьSXXXXXXXXXXXMMMMMMMMMMMMMMMMMMMM.MMMMMMMM

S представляет разряд знака, X — это разряды смещенного показателя степени, а M — это значащие разряды. В форматах одиночной и двойной точности значение самого левого бита предполагается.

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

Специальные значения

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

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

Бесконечность

Значения +∞ и −∞ представляются с экспонентой из одних единиц и мантиссой из одних нулей. Разряд знака определяет знак бесконечности.

Субнормальные числа

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

NaN (не число)

В формате IEEE с плавающей запятой могут быть представлены значения, не являющиеся действительными числами, например 0/0. Значения такого вида называются NaN (не число). Значение NaN представляется состоящим из единиц показателем степени и отличной от нуля значащей частью. Существует два вида значений NaN: несигнальные (QNaN) и сигнальные (SNaN). Для несигнальных значений NaN старший разряд значащей части равен единице, и эти значения распространяются через выражения. Они представляют неопределенные значения, например результат деления на бесконечность или умножения бесконечности на нуль. Для сигнальных значений NaN старший разряд значащей части равен нулю. Эти значения используются для недопустимых операций, указывая на аппаратное исключение, связанное с обработкой чисел с плавающей запятой.

Примеры

Ниже приводятся примеры чисел в формате одиночной точности:

Для значения 2 знаковый бит имеет значение 0. Сохраняется экспонента 128, то есть двоичное значение 1000 0000, вычисляемое как 127 плюс 1. Сохраненный двоичный значащим имеет значение (1). 000 0000 0000 0000 0000 0000, которая имеет неявные начальные значения 1 и binary, поэтому фактический значащим является одним.

ЗначениеФормулаДвоичное представлениеШестнадцатеричный
21 * 2 10100 0000 0000 0000 0000 0000 0000 00000x40000000

Значение –2. То же, что и + 2, однако в этом случае задан разряд знака. Таким же образом задаются отрицательные числа во всех форматах IEEE с плавающей запятой.

ЗначениеФормулаДвоичное представлениеШестнадцатеричный
-2–1 * 2 11100 0000 0000 0000 0000 0000 0000 00000xC0000000

Значение 4. Та же значащая часть, показатель степени увеличивается на единицу (смещенное значение 129 или 100 0000 1 в двоичном формате).

ЗначениеФормулаДвоичное представлениеШестнадцатеричный
41 * 2 20100 0000 1000 0000 0000 0000 0000 00000x40800000

Значение 6. Тот же показатель степени; значащая часть увеличивается наполовину. Это (1.) 100 0000. 0000 0000, что, поскольку это двоичная дробь, имеет значение 1 1/2, так как значения дробных разрядов равны 1/2, 1/4, 1/8 и т. д.

ЗначениеФормулаДвоичное представлениеШестнадцатеричный
61.5 * 2 20100 0000 1100 0000 0000 0000 0000 00000x40C00000

Значение 1. Та же значащая часть, что и для остальных степеней двух; смещенный показатель степени на единицу меньше, чем у двух при 127, то есть 011 1111 1 в двоичном формате.

ЗначениеФормулаДвоичное представлениеШестнадцатеричный
11 * 2 00011 1111 1000 0000 0000 0000 0000 00000x3F800000

Значение 0,75. Смещенный показатель степени равен 126, 011 1111 0 в двоичном формате, а значащим имеет значение (1). 100 0000. 0000 0000, то есть 1 1/2.

Значение 2,5. Так же, как и два, однако в значащей части задан разряд, который представляет 1/4.

ЗначениеФормулаДвоичное представлениеШестнадцатеричный
2.51.25 * 2 10100 0000 0010 0000 0000 0000 0000 00000x40200000

1/10 — это повторяющаяся часть в двоичном формате. Значащая часть здесь немного меньше 1,6, а экспонента с учетом смещения указывает, что 1,6 нужно разделить на 16. (Это 011 1101 1 в двоичном формате, то есть 123 в десятичном формате.) Фактический показатель степени 123 – 127 = –4. Это значит, что выполняется умножение на 2 –4 = 1/16. Хранимая в памяти значащая часть округляется до последнего разряда, чтобы представить выходящие за пределы числа с максимально возможной точностью. (Величины 1/10 и 1/100 нельзя точно представить в двоичном формате по той же причине, по которой 1/3 нельзя представить в десятичном.)

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

Источник

Что нужно знать про арифметику с плавающей запятой

Что такое ieee 754. Смотреть фото Что такое ieee 754. Смотреть картинку Что такое ieee 754. Картинка про Что такое ieee 754. Фото Что такое ieee 754

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

Арифметика с плавающей запятой почему-то считается экзотической областью компьютерных наук, учитывая, что соответствующие типы данных присутствуют в каждом языке программирования. Я сам, если честно, никогда не придавал особого значения компьютерной арифметике, пока решая одну и ту же задачу на CPU и GPU получил разный результат. Оказалось, что в потайных углах этой области скрываются очень любопытные и странные явления: некоммутативность и неассоциативность арифметических операций, ноль со знаком, разность неравных чисел дает ноль, и прочее. Корни этого айсберга уходят глубоко в математику, а я под катом постараюсь обрисовать лишь то, что лежит на поверхности.

1. Основы

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

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

Что такое ieee 754. Смотреть фото Что такое ieee 754. Смотреть картинку Что такое ieee 754. Картинка про Что такое ieee 754. Фото Что такое ieee 754

Математически это записывается так:

Основание определяет систему счисления разрядов. Математически доказано, что числа с плавающей запятой с базой B=2 (двоичное представление) наиболее устойчивы к ошибкам округления, поэтому на практике встречаются только базы 2 и, реже, 10. Для дальнейшего изложения будем всегда полагать B=2, и формула числа с плавающей запятой будет иметь вид:

Что такое мантисса и порядок? Мантисса – это целое число фиксированной длины, которое представляет старшие разряды действительного числа. Допустим наша мантисса состоит из трех бит (|M|=3). Возьмем, например, число «5», которое в двоичной системе будет равно 1012. Старший бит соответствует 2 2 =4, средний (который у нас равен нулю) 2 1 =2, а младший 2 0 =1. Порядок – это степень базы (двойки) старшего разряда. В нашем случае E=2. Такие числа удобно записывать в так называемом «научном» стандартном виде, например «1.01e+2». Сразу видно, что мантисса состоит из трех знаков, а порядок равен двум.

Допустим мы хотим получить дробное число, используя те же 3 бита мантиссы. Мы можем это сделать, если возьмем, скажем, E=1. Тогда наше число будет равно

2 = 10 (в двоичной системе) = 1.000e+1 = 0.100e+2 = 0.010e+3. (E=1, E=2, E=3 соответственно)

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

Что такое ieee 754. Смотреть фото Что такое ieee 754. Смотреть картинку Что такое ieee 754. Картинка про Что такое ieee 754. Фото Что такое ieee 754

Это экономит один бит, так как неявную единицу не нужно хранить в памяти, и обеспечивает уникальность представления числа. В нашем примере «2» имеет единственное нормализованное представление («1.000e+1»), а мантисса хранится в памяти как «000», т.к. старшая единица подразумевается неявно. Но в нормализованном представлении чисел возникает новая проблема — в такой форме невозможно представить ноль.

Строго говоря, нормализованное число имеет следующий вид:

Качество решения задач во многом зависит от выбора представления чисел с плавающей запятой. Мы плавно подошли к проблеме стандартизации такого представления.

2. Немного истории

В 60-е и 70-е годы не было единого стандарта представления чисел с плавающей запятой, способов округления, арифметических операций. В результате программы были крайне не портабельны. Но еще большей проблемой было то, что у разных компьютеров были свои «странности» и их нужно было знать и учитывать в программе. Например, разница двух не равных чисел возвращала ноль. В результате выражения «X=Y» и «X-Y=0» вступали в противоречие. Умельцы обходили эту проблему очень хитрыми трюками, например, делали присваивание «X=(X-X)+X» перед операциями умножения и деления, чтобы избежать проблем.

Инициатива создать единый стандарт для представления чисел с плавающей запятой подозрительно совпала с попытками в 1976 году компанией Intel разработать «лучшую» арифметику для новых сопроцессоров к 8086 и i432. За разработку взялись ученые киты в этой области, проф. Джон Палмер и Уильям Кэхэн. Последний в своем интервью высказал мнение, что серьезность, с которой Intel разрабатывала свою арифметику, заставила другие компании объединиться и начать процесс стандартизации.

Все были настроены серьезно, ведь очень выгодно продвинуть свою архитектуру и сделать ее стандартной. Свои предложения представили компании DEC, National Superconductor, Zilog, Motorola. Производители мейнфреймов Cray и IBM наблюдали со стороны. Компания Intel, разумеется, тоже представила свою новую арифметику. Авторами предложенной спецификации стали Уильям Кэхэн, Джероми Кунен и Гарольд Стоун и их предложение сразу прозвали «K-C-S».

Практически сразу же были отброшены все предложения, кроме двух: VAX от DEC и «K-C-S» от Intel. Спецификация VAX была значительно проще, уже была реализована в компьютерах PDP-11, и было понятно, как на ней получить максимальную производительность. С другой стороны в «K-C-S» содержалось много полезной функциональности, такой как «специальные» и «денормализованные» числа (подробности ниже).

В «K-C-S» все арифметические алгоритмы заданы строго и требуется, чтобы в реализации результат с ними совпадал. Это позволяет выводить строгие выкладки в рамках этой спецификации. Если раньше математик решал задачу численными методами и доказывал свойства решения, не было никакой гарантии, что эти свойства сохранятся в программе. Строгость арифметики «K-C-S» сделала возможным доказательство теорем, опираясь на арифметику с плавающей запятой.

Компания DEC сделала все, чтобы ее спецификацию сделали стандартом. Она даже заручилась поддержкой некоторых авторитетных ученых в том, что арифметика «K-C-S» в принципе не может достигнуть такой же производительности, как у DEC. Ирония в том, что Intel знала, как сделать свою спецификацию такой же производительной, но эти хитрости были коммерческой тайной. Если бы Intel не уступила и не открыла часть секретов, она бы не смогла сдержать натиск DEC.

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

3. Представление чисел с плавающей запятой сегодня

Разработчики «K-C-S» победили и теперь их детище воплотилось в стандарт IEEE754. Числа с плавающей запятой в нем представлены в виде знака (s), мантиссы (M) и порядка (E) следующим образом:

Замечание. В новом стандарте IEE754-2008 кроме чисел с основанием 2 присутствуют числа с основанием 10, так называемые десятичные (decimal) числа с плавающей запятой.

Чтобы не загромождать читателя чрезмерной информацией, которую можно найти в Википедии, рассмотрим только один тип данных, с одинарной точностью (float). Числа с половинной, двойной и расширенной точностью обладают теми же особенностями, но имеют другой диапазон порядка и мантиссы. В числах одинарной точности (float/single) порядок состоит из 8 бит, а мантисса – из 23. Эффективный порядок определяется как E-127. Например, число 0,15625 будет записано в памяти как

Что такое ieee 754. Смотреть фото Что такое ieee 754. Смотреть картинку Что такое ieee 754. Картинка про Что такое ieee 754. Фото Что такое ieee 754
Рисунок взят из Википедии

3.1 Специальные числа: ноль, бесконечность и неопределенность

Неопределенность или NaN (от not a number) – это представление, придуманное для того, чтобы арифметическая операция могла всегда вернуть какое-то не бессмысленное значение. В IEEE754 NaN представлен как число, в котором E=Emax+1, а мантисса не нулевая. Любая операция с NaN возвращает NaN. При желании в мантиссу можно записывать информацию, которую программа сможет интерпретировать. Стандартом это не оговорено и мантисса чаще всего игнорируется.

Вернемся к примеру. Наш Emin=-1. Введем новое значение порядка, E=-2, при котором числа являются денормализованными. В результате получаем новое представление чисел:

Что такое ieee 754. Смотреть фото Что такое ieee 754. Смотреть картинку Что такое ieee 754. Картинка про Что такое ieee 754. Фото Что такое ieee 754

Интервал от 0 до 0,5 заполняют денормализованные числа, что дает возможность не проваливаться в 0 рассмотренных выше примерах (0,5-0,25 и 1,5-1,25). Это сделало представление более устойчиво к ошибкам округления для чисел, близких к нулю.

Но роскошь использования денормализованного представления чисел в процессоре не дается бесплатно. Из-за того, что такие числа нужно обрабатывать по-другому во всех арифметических операциях, трудно сделать работу в такой арифметике эффективной. Это накладывает дополнительные сложности при реализации АЛУ в процессоре. И хоть денормализованные числа очень полезны, они не являются панацеей и за округлением до нуля все равно нужно следить. Поэтому эта функциональность стала камнем преткновения при разработке стандарта и встретила самое сильное сопротивление.

3.4 Очередность чисел в IEEE754

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

4.2 Неассоциативность арифметических операций

В арифметике с плавающей запятой правило (a*b)*c = a*(b*c) не выполняется для любых арифметических операций. Например,

Допустим у нас есть программа суммирования чисел.

Некоторые компиляторы по умолчанию могут переписать код для использования нескольких АЛУ одновременно (будем считать, что n делится на 2):

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

4.3 Числовые константы

Помните, что не все десятичные числа имеют двоичное представление с плавающей запятой. Например, число «0,2» будет представлено как «0,200000003» в одинарной точности. Соответственно, «0,2 + 0,2 ≈ 0,4». Абсолютная погрешность в отдельном
случае может и не высока, но если использовать такую константу в цикле, можем получить накопленную погрешность.

4.4 Выбор минимума из двух значений
4.5 Сравнение чисел

Очень распространенная ошибка при работе с float-ами возникает при проверке на равенство. Например,

Ошибка здесь, во-первых, в том, что 0,2 не имеет точного двоичного представления, а во-вторых 0,2 – это константа двойной точности, а переменная fValue – одинарной, и никакой гарантии о поведении этого сравнения нет.

Лучший, но все равно ошибочный способ, это сравнивать разницу с допустимой абсолютной погрешностью:

Недостаток такого подхода в том, что погрешность представления числа увеличивается с ростом самого этого числа. Так, если программа ожидает «10000», то приведенное равенство не будет выполняться для ближайшего соседнего числа (10000,000977). Это особенно актуально, если в программе имеется преобразование из одинарной точности в двойную.

Выбрать правильную процедуру сравнения сложно и заинтересованных читателей я отсылаю к статье Брюса Доусона. В ней предлагается сравнивать числа с плавающей запятой преобразованием к целочисленной переменной. Это — лучший, хотя и не портабельный способ:

5. Проверка полноты поддержки IEE754

Думаете, что если процессоры полностью соответствуют стандарту IEEE754, то любая программа, использующая стандартные типы данных (такие как float/double в Си), будет выдавать один и тот же результат на разных компьютерах? Ошибаетесь. На портабельность и соответствие стандарту влияет компилятор и опции оптимизации. Уильям Кэхэн написал программу на Си (есть версия и для Фортрана), которая позволяет проверить удовлетворяет ли связка «архитектура+компилятор+опции» IEEE754. Называется она «Floating point paranoia» и ее исходные тексты доступны для скачивания. Аналогичная программа доступна для GPU. Так, например, компилятор Intel (icc) по умолчанию использует «расслабленную» модель IEEE754, и в результате не все тесты выполняются. Опция «-fp-model precise» позволяет компилировать программу с точным соответствием стандарту. В компиляторе GCC есть опция «-ffast-math», использование которой приводит к несоответствию IEEE754.

Заключение

Напоследок поучительная история. Когда я работал над тестовым проектом на GPU, у меня была последовательная и параллельная версия одной программы. Сравнив время выполнения, я был очень обрадован, так как получил ускорение в 300 раз. Но позже оказалось, что вычисления на GPU «разваливались» и обращались в NaN, а работа с ними в GPU была быстрее, чем с обычными числами. Интересно было другое — одна и та же программа на эмуляторе GPU (на CPU) выдавала корректный результат, а на самом GPU – нет. Позже оказалось, что проблема была в том, что этот GPU не поддерживал полностью стандарт IEEE754 и прямой подход не сработал.

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

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *