Ieee754 — Числа в формате IEEE754 на JAVA


Содержание

Изучение компьютерной арифметики

Типы данных с плавающей запятой в Стандарте IEEE-754

Рубрика:&nbsp Арифметика с плавающей запятой → IEEE-754 → Основы

Показаны типы данных, которые поддерживает Стандарт. Подробно рассмотрен тип binary32.

Формат IEEE-754 предоставляет возможность уместить число с плавающей запятой с определённой точностью в полях размером от 16 до 128 бит. Опишем эти типы данных:

  • binary16 (половинная точность, half precision),
  • binary32 (одинарная точность, single precision),
  • binary64 (двойная точность, double precision) и
  • binary128 (учетверённая точность, quadruple precision).

Есть также упоминание о формате вроде binary256 (увосмерённая точность, octuple precision) и краткие рекомендации по форматам с расширенной точностью (extended precision formats). Например, формат с расширенной точностью размером 80 бит используется в FPU (x87), но в настоящее время задействуется крайне редко. Ряд компиляторов (например, Visual C++ последних версий) даже не поддерживает подобный тип данных, который обычно называется «long double». Его использование крайне не рекомендуется. Ниже представлена таблица значений $p$, $E$, $e_$ и $e_$ для указанных форматов.

Цифры в названии формата показывают число бит, используемое для двоичного кодирования чисел, в нём представленных.

Binary32

Давайте начнём изучение IEEE-754 с чисел одинарной точности binary32. Этот тип данных поддерживается многими языками, в том числе Си и Си++ (тип данных «float»), так что мы сможем сразу проверить наши знания на практике. В формате binary32 под экспоненту выделено 8 бит (E=8), а под дробную часть мантиссы — 23 (p=24), ещё один бит остаётся для знака.

Итак, пронумеруем биты числа от 0 до 31, а всё пространство из 32 битов разделим на три секции так, как указано на картинке:

Первое поле, синего цвета, занимающее один бит с номером 31, отвечает за знак числа. Второе, зелёное, поле, занимающее биты с 23-го по 30-й, относится к экспоненте. Как мы помним из логики Стандарта IEEE-754, в этом поле сохраняется смещённая экспонента $e_b=e+\mathrm$, а смещение $\mathrm$ равно $127$. Последнее поле, красное, занимающее 23 бита от 0-го до 22-го отвечает за мантиссу, точнее, за её дробную часть, потому как старший значащий бит (бит целой части) мы не храним явно.

Рассмотрим пример. Число 3,14 запишется в виде $1<,>100\,100\,011\,110\,101\,110\,000\,11_<(2)>×2^1$ (мы взяли только 23 цифры после запятой, правильно округлив значение, больше цифр нам не нужно). Наши 23 цифры дробной части — это 10010001111010111000011. Значение смещённой экспоненты будет равно $e_b=1+127=128=10000000_<(2)>$. Таким образом, в двоичном коде с плавающей запятой число 3,14 примет вид:

0 10000000 10010001111010111000011

И здесь начинается то, с чем в действительности столкнётся каждый, кто будет работать с плавающей арифметикой. Смотрите внимательно! Давайте попробуем перевести наше число обратно в десятичный формат:

Если вы не вполне понимаете, откуда в знаменателях эти степени двойки, то поглядите на те позиции мантиссы, на которых стоят единицы (слева направо, начиная отсчёт от единицы). Единицы стоят в первой позиции, затем в четвёртой, затем в восьмой и так далее до позиций 22 и 23. Неявная единица — это как будто 1/2 0 .

Итак, наше число 3,14 не может быть точно представлено с использованием 23 битов после десятичной запятой, поэтому оно округляется до ближайшего числа, представимого в таком формате. Эта особенность плавающей арифметики должна совершенно жёстко закрепиться в вашей памяти. В прикладных расчётах вообще редко встречаются числа, точно представимые в двоичной арифметике с плавающей точкой, всегда есть некоторая погрешность. В нашем примере точность составляет не меньше 10 —6 (разница между исходным и приближённым числами не превышает одной миллионной).

Давайте потренируемся. Возьмём число 25. В двоичном коде оно будет иметь вид 11001. В нормализованной научной нотации: 1,1001×2 4 . Таким образом, смещённая экспонента равна $e_b=4+127=131=10000011_<(2)>$, мантисса (когда мы уберём старший бит и дополним последовательность нулями до 23-х бит) равна 10010000000000000000000. Таким образом, число 25 в формате binary32 примет вид:

0 10000011 10010000000000000000000

Другой пример, число −0,3515625. В нормализованной научной нотации примет вид −1,01101×2 −2 . Смещённая экспонента $e_b=-2+127=125=01111101_<(2)>$. Мантисса равна 01101000000000000000000, а поскольку число отрицательное, знаковый бит будет единичным. В итоге, получим запись:

1 01111101 01101000000000000000000

Интересен также пример конвертирования числа 1. Его экспонента равна , поэтому смещённая экспонента примет вид $e_b=127=01111111_<(2)>$, а мантисса будет состоять из одних нулей:

0 01111111 00000000000000000000000

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

  • 0 10000011 10010000000000000000000 = 0x41C80000 = 25,0
  • 1 01111101 01101000000000000000000 = 0xBEB40000 = −0,3515625
  • 0 01111111 00000000000000000000000 = 0x3F800000 = 1.0

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

Попробуем выполнить обратную операцию. Пусть в формате binary32 нам дано число 0x449A4000, требуется перевести его в привычную нам десятичную запись. Разбиваем его на три битовых поля:

0 10001001 00110100100000000000000 = 0x449A4000

Смещённая экспонента равна $e_b=137$, то есть порядок числа e=10. Таким образом, всё число имеет значение $$ \bigl( 1+2^<-3>+2^<-4>+2^<-6>+2^ <-9>\bigr) \times 2^ <10>= 1\,234. $$

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

Как уже было сказано, стандарт IEEE-754 предоставляет 4 способа округления: к нулю (towards zero), к минус бесконечности (towards minus infinity), к плюс бесконечности (towards plus infinity) и к ближайшему целому, либо к чётному (half to even).

Рассмотрим число 1+2 −23 . В научной нотации оно будет записано как $1<,>000\,000\,000\,000\,000\,000\,000\,01 \times 2^0$. Это число точно представимо в указанном формате, поэтому не требует округлений. Размера мантиссы хватает как раз на то, чтобы уместить в себя 23-й единичный бит дробной части:

0 01111111 00000000000000000000001

Теперь возьмём 1+2 −23 +2 −24 . $$\require1<,>000\,000\,000\,000\,000\,000\,000\,01\colorbox <1>\times 2^0.$$

Нам не хватает одного бита в поле мантиссы, чтобы уместить последний 24-й бит дробной части. Следовательно, требуется округление. Но в какую сторону? Правило half to even требует в случае неоднозначности округлять в сторону чётной мантиссы. То есть получаем 1+2 −23 +2 −24 ≈1+2 −22 :

0 01111111 00000000000000000000010

Теперь возьмём 1+2 −23 +2 −25 : $$\require1<,>000\,000\,000\,000\,000\,000\,000\,01\colorbox<0>1 \times 2^0.$$ Здесь мы не видим спорного случая, поэтому однозначно округляется книзу 1+2 −23 +2 −25 ≈1+2 −23 .

0 01111111 00000000000000000000001

Самое маленькое число, которое можно представить в нормализованной научной нотации, это число $1<,>000\,000\,000\,000\,000\,000\,000\,00 \times 2^ <-126>= 2^<-126>\approx1<,>18\times 10^<-38>$. У него минимально возможная экспонента −126 и в двоичном коде оно записывается как

0 00000001 00000000000000000000000 = 0x00800000

Максимальное число имеет максимально возможную экспоненту 127 и имеет вид $1<,>111\,111\,111\,111\,111\,111\,111\,11 \times 2^ <127>= (2-2^<-23>)\times 2^<127>\approx3<,>4\times 10^<38>$.

В двоичном коде это будет выглядеть как


0 11111110 11111111111111111111111 = 0x7F7FFFFF

Если значение смещённой экспоненты равно нулю, то мы имеем дело с денормализованными числами. Значение экспоненты полагается равным e=-126. То есть денормализованные числа имеют вид 0,xxx…×2 −126 . Получается, что самое маленькое число, представимое в формате binary32 имеет вид $$0<,>000\,000\,000\,000\,000\,000\,000\,01 \times 2^ <-126>= 2^<-126-23>=2^<-149>\approx1<,>4\times10^<-45>.$$

В двоичном коде:

0 00000000 00000000000000000000001 = 0x00000001

Если $e_b = 255$, то есть поле экспоненты заполняют только единичные биты, мы имеем дело с бесконечностями или NaN’ами Поле знака, соответственно, отвечает за знак бесконечности и не имеет смысла для NaN.

  • 0 11111111 00000000000000000000000 = 0x7F800000 = +oo
  • 1 11111111 00000000000000000000000 = 0xFF800000 = -oo

«Не число» NaN кодируется всеми единичками в поле экспоненты и ненулевой мантиссой:

  • 0 11111111 10000000000000000000000 = 0x7FС00000 = NaN
  • 1 11111111 00000000000000000000010 = 0xFF800002 = NaN

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

Например, на VC++ 2015 вывод этой программы будет таким:

Обратите, пожалуйста, внимание, что некоторые значение отражены не точно. Скажем, число 0,1(10) не может быть точно представлено в двоичной системе счисления. В двоичной научной нотации оно будет выглядеть как 1,(1001)×2 −4 . Таким образом, ближайшее число, точно представимое в формате binary32, будет значиться как (округление произошло вверх) $1<,>100\,110\,011\,001\,100\,110\,011\,01 \times 2^ <-4>= 0<,>100\,000\,001\,490\,116\,119\,384\,765\,625$

То есть число 0,1 удалось в этом формате закодировать с точностью не меньше 10 −8 . То же самое можно сказать о числе 1/3. В двоичной научной нотации оно будет записано как 1,(01)×2 −2 , а значит ближайшее точно представимое значение будет (после округления вверх) $1<,>010\,101\,010\,101\,010\,101\,010\,11 \times 2^ <-2>= 0<,>333\,333\,343\,267\,440\,795\,898\,437\,5$.

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

Взглянув на таблицу, можно сделать вывод о том, что формат binary32 «держит» около 7 значащих цифр. Однако для денормализованных чисел эта точность может быть ниже. С каждой арифметической операцией точность может падать, причём иногда очень существенно.

Это была заключительная статья данной серии.
Предыдущая: «Компьютерное представление чисел с плавающей запятой»
Содержание Все права защищены © Артём Михайлович Караваев, 2020. При копировании материала прошу указывать ссылку на источник

Числа с плавающей точкой/запятой согласно стандарту IEEE754-2008

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

Если у вас на компьютере больше гигабайта оперативной памяти и вы считаете, что для современных ЭВМ вопрос выбора формата хранения данных при программировании неактуален, напомним, что также существует мир микроконтроллеров, по сути тех же ЭВМ, чьи объёмы памяти на 1-2 порядка меньше. Даже SIM-карту телефона (или банковскую карту с чипом) можно в какой-то мере рассматривать как специфическую ЭВМ, не говоря уже о том, что во многих автомобилях управление устройствами происходит по CAN-шине, работа с которой не обходится без ЭВМ.

Какой тип выбрать?

Перед началом использования типов попробуем понять, что для представления действительных чисел также существует несколько «сущностей» (по аналогии с рис. 2.1 сущность – это некоторая модель представления действительных чисел и соответствующий ей формат записи числа на бумаге или в памяти ЭВМ) (см. рис. 2.2).

По мнению авторов, направление «движения мыслей» наиболее естественно происходит по стрелкам, хотя ничто не мешает вам двигаться и в обратном направлении, даже «перескакивать» через отдельные сущности. Так как за каждой сущностью фактически стоит одна или несколько моделей представления действительных чисел, то высказать однозначно мнение, что какая-то сущность (и как следствие ‒ какой-то формат записи) лучше и что надо использовать только её, нельзя.

«Пробежимся» по графу, изображённому выше на рис. 2.2 от «числа» до его представления в памяти ЭВМ на примере показания термометра (см. табл. 2.6).

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

Опираясь на основы моделирования (представление чисел – это модель) и глядя в таблицу легко догадаться, что:

  • каждая модель имеет свои ограничения;
  • достоверность (точность) представления чисел для каждой модели различна;
  • в некоторых сущностях числа могут иметь несколько форм записи;
  • преобразования чисел из одной сущности в другую могут быть неоднозначными.

Таблица 2.6. Форматы числа в разных сущностях
Сущность Описание, форматы Значение
Действительное число мера чего-то, зависит от того, в чём и как измеряют (в нашем случае это высота столбика ртути в условных единицах пропорционально измеренной температуре)
Десятичная система счисления
  • естественная форма записи счисления
  • нормализованный экспоненциальный вид
  • денормализованный экспоненциальный вид
  • 36,6
    3,66∙10 1
    0,366∙10 2
    Двоичная система счисления
  • естественная форма записи
  • форма с плавающей запятой в экспоненциальном нормализованном виде
  • форма с плавающей запятой в экспоненциальном денормализованном виде
  • 100100,100110011001100110. 1,00100100110011001100110. ∙2 101 0,10010010011001100110011. ∙2 110
    Промежуточный вид IEEE 754 Преобразование двоичного нормализованного числа в binary32 формат стандарта IEEE 754 0 10000100 00100100110011001100110
    Двоичная форма представления в ЭВМ Непосредственное хранение в представления в памяти ЭВМ (для архитектуры LITTLE_ENDIAN байты хранятся в обратном порядке) 01100110 01100110 00010010 01000010
    Шестнадцатеричная форма представления ячеек памяти в ЭВМ Компактная форма записи содержимого памяти 66 66 12 42
    • либо заранее преобразовывать все числа к единой форме,
    • либо создать специальные алгоритмы распознавания формата числа,
    • либо указывать каждый раз его форму записи.

    Все три варианта в той или иной мере используются.

    Практическая проверка правильности вычислений показала, что предыдущие преобразования верны. Если проводимые вычисления не показались вам сложными и вы считаете, что уже умеете преобразовывать любые числа по формату IEE754, то спешим вас огорчить, рано радуетесь. Если бы мы говорили о формате хранения целых беззнаковых чисел, то можно было бы «остановиться», так как для них используется всего лишь одна формула преобразований. В случае же с действительными числами забежим вперёд и скажем, что таких формул будет 10! В примере выше мы использовали лишь одну, ниже разберём остальные. В этом, наверное, и кроется основная проблема изучения формата хранения чисел, когда обучаемыми рассматриваются лишь некоторые случаи преобразований, а все остальные уходят из рассмотрения.

    Понять сказанное проще, проведя рассуждения «от обратного», а именно «от памяти к числу». Так как для хранения данных одной переменной типа float у нас задействовано 32 двоичных разряда, то максимальное число вариантов будет 2 32 , начиная 32 «нулями» и заканчивая всеми «единицами». Записывать числа удобнее в более компактной шестнадцатеричной форме, где начало и конец будут 00 00 00 00 и FF FF FF FF. см. табл. 2.8a.

    Рассмотрим подробнее рис. 2.3. Над воображаемой осью координат «x» записаны значения ячеек памяти. Под осью записаны значения чисел, а цветом указаны «форму- лы», по которым можно осуществить преобразования, причём с целью упрощения и исходя из симметрии их число (как и цветов на рис., оттенков при чёрно-белом изда- нии) сокращено до пяти. «Пробежимся» по положительной части оси и разберём их.


    «Ноль – он и в Африке ноль». Для представления нуля в памяти используется комбинация нулей во всех 32 разрядах. Согласитесь, что это тривиально и легко запомнить.

    Фрагмент памяти ЭВМ, содержащий значения 00 00 00 0016 (следует учитывать, что реальная последовательность хранения зависит от архитектуры, см. стр. 36), будучи интерпретирован как число формата binary32 IEEE754-2008, считается числом «+0».

    Следует отметить, что если рассматривать «отрицательную область», то там тоже будет «свой» ноль.

    Из рисунков видно, что при шестнадцатеричной записи в памяти отображение «–0» будет как 80 00 00 00 (следует учитывать, что реальная последовательность хранения зависит от архитектуры и может быть обратной, см. стр. 36).

    При кодировании целых чисел одним байтом от значения «−0» отказались в пользу ещё одного отрицательного числа, вот почему при 256 вариантах мы пользуемся не симметричным диапазоном [−127, +127], а асимметричным [−128, +127], как и [−32768, +32767] и т. д. Смею предположить, что «+0» и «−0», с точки зрения математики, если не рассматривать пределы справа и слева, есть одно и то же – «0», а в чём различие «+» и «−» – философский вопрос. Однако из факта существования двух нулей технически можно сделать интересные выводы, например для операции сравнения. Если ранее, при использовании целых чисел, из равенства «представления чисел в памяти ЭВМ» следовало и равенство самих чисел, то для типов с плавающей запятой одним сравнением уже не обойтись. Например, при сравнении фрагментов памяти 80 00 00 00 и 00 00 00 00, хранящих числа с плавающей запятой, побитно видно, что они различаются, а значит, можно ошибочно предположить, что числа, представленные данными записями, разные, по факту же мы понимаем, что числа равны.

    Замечание, открытый вопрос

    Почему комбинация 80 00 00 0016 не была использована для представления какого-нибудь ещё числа, как это было сделано с целыми типами?

    Смеем предположить, что с целыми типами, при использовании 8 бит, «выигрыш» оказался существен, плюс несложность добавления числа «на край» отрицательных чисел подсказала простое решение, как использовать это значение. Целые типы с большим числом разрядов просто унаследовали данный подход. Что же касается чисел с плавающей запятой, видимо, даже при разработке стандарта IEEE754 сочли вклад 1/216 для формата Binary16 несущественным, не говоря уже о меньшем вкладе 1/232 для формата binary32 и т. д. Следует отметить, что в «блоке NaN», о котором написано ниже, заложено больше неиспользуемых значений.

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

    Денормализованные числа – это числа, которые нельзя представить в нормализованной форме по формуле № 1. Попытаемся ответить на вопрос: «В чём преимущество денормализованных чисел?» Чтобы ответить на этот вопрос, разберёмся, чем они отличаются от нормализованных, тогда всё и встанет на свои места. Рассуждения ниже по большей части основаны на материале, взятом из [19], который был переработан и дополнен, устранены ошибки. Для упрощения изложения рассмотрим «игрушечный» формат «несуществующий binary5», в котором возможно не только представить, но и перебрать все 2 5 = 32 вариантов чисел для большей ясности.

    Таблица 2.9. Параметры формата «несуществующий binary5»

    В придуманном нами пятибитовом формате возможно представить 16 чисел со знаком «+» (см. табл. 2.10), размещение которых на числовой оси представлено на рис.2.6.

    . подробнее см. в бумажном издании, либо по запросу на почту.

    Ieee754 — Числа в формате IEEE754 на JAVA

    Юровицкий В.М. МФТИ, РГСУ, Москва, www.yur..ru

    Представим, что в наши дни на Землю сошел Сатана, и решил он извести род человеческий. Причем сделать это совершенно незаметно и «естественно».

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

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

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

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

    Итак, чтобы погубить человечество, Сатане достаточно внести замаскированную ошибку в компьютерную программу числовой обработки.

    Но этого делать совсем не надо.

    Потому что это уже есть .

    Типы числовой информации и программы их обработки

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

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

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

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

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

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

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

    Часто используемое терминологическое описание данного типа информации как «числа с плавающей точкой (запятой)» неверно и бессмысленно математически.

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

    Еще одно часто употребляемое название для этого класса числовой информации – «вещественные» числа. Но и это неадекватная терминология. Термин «вещественный» используется в математике для различения от понятия «мнимый». С этой точки зрения и целые числа также являются вещественными. А «мнимости» в компутинге в ее базисной (арифметической) системе обработки вообще не используются.

    Поэтому на основе используемых средств обработки (стандарт IEEE 754) элементы этого типа числовой информации надо по праву назвать IEEE754- числами.

    IEEE754- числа и IEEE754- тика

    Математической базой использования IEEE754- чисел есть математическая теория функций действительного переменного. Действительно, компьютерная работа с IEEE754- числами представляет собой отражение теоретической математики на множестве действительных чисел. Поэтому представляется, казалось бы, логичным IEEE754- числа называть «действительными» числами». Этот термин также используется в компутинге.

    К сожалению, и термин «действительные» не отражает адекватно сущность и свойства IEEE754- чисел.

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

    Форматы IEEE754- чисел

    Общая длина представления

    Длина мантиссы

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

    Одинарной точности


    32 бит

    23 бит

    Двойной точности

    64 бит

    52 бит

    Расширенной точности

    80 бит

    64 бит

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

    В настоящее время используются приборы точности не выше класса 0.1%. Это соответствует 4-5 десятичным разрядам. Потому большая часть мантисс IEEE754- чисел, особенно в форматах двойной и расширенной точности, несодержательна, фактически, есть информационный шум. Отсюда следует, что современный IEEE754- процессинг есть процессинг, обработка преимущественно шумов. И соответственно выходные данные этого процессинга являются сверхзашумленными. Фильтрация этих шумов, выделение содержательной части IEEE754- чисел осуществляется человеком (например, программистом при планировании вывода результатов) по интуиции, а не на основе твердых правил и алгоритмов. Понятно, насколько все это далеко от научных представлений теории информации – информатики. Область работы с метрологическими данными оказывается наименее научно обоснована и примитивна.

    Рассмотрим теперь, насколько обосновано отождествление IEEE754- чисел с математическими действительными числами.

    Пусть имеем IEEE754- число 1.0 в представлении ординарной точности. Это число будет иметь мантиссу в виде 10000000 (в десятичном представлении) и некоторую степень.

    Но легко видеть, что действительные числа с той же самой степенью и мантиссами 1000000023456, 1000000045, 1000000000007654 и т.п. будут представлены тем же самым действительным числом 1.0. Таким образом, между действительными и IEEE754- числами существует соответствие – одно IEEE754- число соответствует бесконечному множеству действительных чисел. Можно показать, что это множество имеет древовидную структуру.

    В теории функций действительного переменного нет таким структур действительных чисел, Аргументы и функции в этой теории есть действительные числа, а не их множества. Все действия в математике действительных чисел осуществляются над множествами самих действительных чисел, а не над множеством множеств действительных чисел. Поэтому между IEEE754- числами и действительными числами нет соответствия. И недопустимо эти числа отождествлять и называть IEEE754- числа действительными числами.

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

    Пусть даны два вещественных вектора x и y: x = (10 20 , 1223, 10 18 , 10 15 , 3,−10 12 ), y = (10 20 , 2,−10 22 , 10 13 , 2111, 10 16 ). Обозначим скалярное произведение x и y через x * y ( соответственные элементы перемножаются и эти произведения складываются ). В точной целочисленной арифметике имеем : x * y = 1040 + 2446 1040 + 1028 + 6333 1028 = 8779. Однако арифметика чисел с плавающей точкой на любом современном компьютере ( включая те , на которых арифметика реализована в соответствии со стандартом IEEE 754 даст для такого скалярного произведения нулевое значение

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

    А вот в вычислительном стандарте IEEE 754 это уравнение имеет решение при любом α. Ответ зависит от типа IEEE754- чисел. Найдем, к примеру, решение этого уравнения при α=100 в формате расширенной точности (используем калькулятор WINDOWS, работающий, естественно, в стандарте IEEE 754). Результат легко вычисляется: x=2,7342203691457758866577330101202e+32.

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

    И отсюда мы можем понять, для чего в IEEE754- тике желательно использовать большие форматы. Дело в том, что расхождение IEEE754- тики с математикой зачастую (но не всегда) отмечается появлением больших чисел, как это видно по приведенному примеру. Причем чем больше формат IEEE754- числа, тем большие возникают числа. Например, при использовании формата одинарной точности в предыдущей задаче х имело бы уже значение по порядку величины 10 8 , Ясно, что чем больше неверные результаты выбивается из среднего уровня, тем легче их идентифицировать. Но это возможно лишь при допущении вмешательстве человека в управляемую и контролируемую компьютером систему. Второй важный момент состоит в том, что при резком увеличении сложности и объемов вычислительной работы этот идентифицирующий признак теряет свое значение. А направление развития современной цивилизации как раз и состоит и в исключении человека как «слабого звена» и полной автоматизации, и в увеличении объемов вычислительной работы и мощностей компьютеров. Таким образом, цивилизационное развитие идет в направлении увеличения вероятности неправильных, «аматематических» результатов компьютерных расчетов и уменьшении вероятности их идентификации и «обезвреживания». А воздействие на управляемую компьютером систему «аматематики» может иметь самый различный характер. Этот результат может пройти без последствий, но может привести и к самым существенным воздействиям вплоть до катастрофических.

    Вот мнение авторитетных исследователей

    Постепенно у критически настроенных исследователей все чаще стал возникать вопрос, вынесенный в заголовок обобщающей статьи немецкого математика проф. К . Никеля : «Can we trust the results of our computing?» (« Можем ли мы доверять результатам наших вычислений?») Действительно, беспристрастный анализ традиционного подхода к численным вычислениям и соответствующего инструментария (алгоритмов, языков программирования и аппаратного обеспечения), проведенный специалистами в области вычислительной математики, привел к неутешительному выводу о том, что алгоритм, сформулированный в столь привычных нам терминах, попросту недоопределен и потому обладает, вообще говоря, непредсказуемыми свойствами. В классическом анализе погрешностей принято оценивать погрешности, возникающие при каждой отдельной операции численных алгоритмов. Конечно, для такого алгоритма, в котором за час выполняется 10 15 операций с плавающей точкой, это уже практически неосуществимо. Поэтому реалистичный анализ погрешностей обычно и не производится. В действительности, сам факт, что вычисленный результат может вообще не иметь верных цифр , редко принимается во внимание.

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

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

    – Взрыв ракеты «Пэтриот» в Саудовской Аравии 25 февраля 1991, который привел к гибели 28 человек, связан с ошибками округления.

    – Взрыв ракеты Ариан-5 сразу после старта при ее первом испытании во Французской Гвиане 4 июня 1996 был следствием переполнения числовой сетки компьютера.

    –23 августа 1991 в Гандсфиорде в Норвегии затонула нефтяная платформа, что привело к убытку почти в один миллиард долларов. Это, как предполагается, было результатом inaccurate finite element analysis .

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

    А в будущем вероятность таких аварий и их тяжесть будет лишь увеличиваться. Что мы можем еще ожидать? Нового Чернобыля из-за ошибки при управлении атомной станцией? Самозапуска ракеты с ядерным зарядом? Самопроизвольного взрыва термоядерного заряда из-за ошибки, допущенной при его конструктивном расчете? Да чего угодно.

    Закладка Сатаны приведена в действие .

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

    Но чем же ответило передовое компьютерное сообщество на эти вызовы?

    Оно ответило созданием концепции и софтвером так называемых «достоверных вычислений».

    Уже в самом этом названии содержится уничтожающая характеристика нынешней вычислительной технологии. Ибо этим самым эта группа специалистов открыто признает нынешнюю вычислительную технологию «недостоверной». Но разве имеет право на существование «недостоверная» вычислительная технология? А если она и предлагается потребителям компьютеров и вычислительного программного обеспечения, то не обязаны ли эти фирмы прямо и открыто информировать потребителей, покупателей и заказчиков о недостоверности этих техник и технологий? В принципе. вполне можно подавать иск к фирмам Интел и Майкрософт за утаивание существенного факта о характеристиках их товаров..

    Но посмотрим, действительно ли ответ на вызов адекватен самой угрозе и нейтрализует недостатки IEEE754- тики?

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

    Эта критика сводилась к нескольким моментам.

    Исходные погрешности данных в процессе интервальных вычислений расширяются совершенно недопустимым образом. Ведь в этой технологии происходит суммирование всех ошибок при любых операциях. Например, при сложении и вычитании 1000 чисел величиной порядка 100 с ошибкой 1 суммарная ошибка будет 1000, в то время как сам результат может быть, к примеру, 500.. Получаем бессмысленный результат – ошибка числа больше самого числа.

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

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

    Рассмотрим две совокупности числовых данных (201, 203) и (5, 12345.6574809). Спросим, можно ли интерпретировать оба набора как математические интервалы? Ответ бесспорно положительный. Но спросим, имеют ли эти математические интервалы практический смысл, существуют ли области науки и техники, данные в которых могли бы быть ими представлены? Ответ: первый интервал имеет практический смысл, например, это интервал для величины электрического напряжения, расстояния и т.д. Но мы не можем найти никакого примера использования второго интервала. Нет ни одной области (нематематической) науки, техники и практики, в которых ннтервал второго типа мог бы использоваться. Таким образом, в практике используются математические интервалы, но отнюдь не произвольные, а лишь определенные, специфицированные. Потому и система математической обработки должна предусматривать возможность обработки не любых интервалов и выдавать в качестве результатов также не любые интервалы, а лишь определенные, специфицированные. Использования любых математических интервалов есть главнейший порок интервального анализа.

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

    Интервальная вычислительная технология является чрезвычайно затратной по используемым ресурсам. Объем операций растет экспоненциально по мере роста количества аргументов. В настоящее время разработано достаточно много искусственных приемов для уменьшения объемов вычислительной работы при интервальных вычислениях. Но это все касается лишь отдельных задач и программ. А стандарт, увы, увеличивает потребность в вычислительных ресурсах на порядки.


    Но главный порок компьютерной технологии достоверных вычислений состоит в том, что она целиком основана на IEEE754- тике. Ведь если IEEE754- тика порочна, то не может не быть порочной и основанная на ней технология. И нет разницы, что вычисляется ошибочно – числа или границы интервалов.

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

    « Математическая модель будет адекватной и работоспособной лишь в том случае, если погрешности вычислений контролируются »

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

    Главная ошибка самого подхода к математической обработке числовых данных на компьютере состоит в попытке воспроизвести на нем невозможное – объекты теоретической математики , такие как действительные числа и интервалы действительных чисел . Компьютеринг нуждается в принципиально новых математических конструкциях , которые более адекватно отражали бы как потребности практики , так и возможности компьютеров . И первым шагом должны стать признание некорректности стандарта IEEE 754, а затем и разработка новых стандартов обработки нецелочисленных данных.

    Где же искать эти новые принципы и концепции? Куда направить свой взор для поиска?

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

    Правила ввода чисел

    1. Числа в десятичной системе счисления могут вводиться как без дробной, так и с дробной частью ( 234234.455 ).
    2. Числа в двоичной системе счисления состоят только из цифр 0 и 1 ( 10100.01 ).
    3. Числа в шестнадцатеричной системе счисления состоят из цифр 0 . 9 и букв A . F .
    4. Можно также получать обратное представление кода (из шестнадцатеричной системы счисления в десятичную, 40B00000 )

    Пример №2 . Представить двоичное число 101.102 в нормализованном виде, записать в 32-битом стандарте IEEE754.
    Решение.
    Представление двоичного числа с плавающей точкой в экспоненциальном нормализованном виде.
    Сдвинем число на 2 разрядов вправо. В результате мы получили основные составляющие экспоненциального нормализованного двоичного числа:
    Мантисса M=1.011
    Экспонента exp2=2
    Преобразование двоичного нормализованного числа в 32 битный формат IEEE 754.
    Первый бит отводится для обозначения знака числа. Поскольку число положительное, то первый бит равен 0
    Следующие 8 бит (с 2-го по 9-й) отведены под экспоненту.
    Для определения знака экспоненты, чтобы не вводить ещё один бит знака, добавляют смещение к экспоненте в половину байта +127. Таким образом, наша экспонента: 2 + 127 = 129
    Переведем экспоненту в двоичное представление.
    Оставшиеся 23 бита отводят для мантиссы. У нормализованной двоичной мантиссы первый бит всегда равен 1, так как число лежит в диапазоне 1 ≤ M 22 *0 + 2 21 *1 + 2 20 *1 + 2 19 *0 + 2 18 *0 + 2 17 *0 + 2 16 *0 + 2 15 *0 + 2 14 *0 + 2 13 *0 + 2 12 *0 + 2 11 *0 + 2 10 *0 + 2 9 *0 + 2 8 *0 + 2 7 *0 + 2 6 *0 + 2 5 *0 + 2 4 *0 + 2 3 *0 + 2 2 *0 + 2 1 *0 + 2 0 *0 = 0 + 2097152 + 1048576 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 = 3145728
    В десятичном коде мантисса выражается числом 3145728
    В результате число 101.10 представленное в IEEE 754 c одинарной точностью равно 01000000101100000000000000000000.
    Переведем в шестнадцатеричное представление.
    Разделим исходный код на группы по 4 разряда.
    010000001011000000000000000000002 = 0100 0000 1011 0000 0000 0000 0000 0000 2
    Получаем число:
    0100 0000 1011 0000 0000 0000 0000 0000 2 = 40B0000016

    Как преобразовать десятичное число в формат с плавающей запятой IEEE 754 с одной точностью?

    Как я могу вручную изменить десятичное (базовое 10) число в формат с плавающей запятой IEEE 754 с одной точностью? Я понимаю, что в нем есть три части: знак, показатель и мантисса. Я просто не совсем понимаю, что на самом деле представляют собой последние две части.

    3 ответов

    найдите наибольшую мощность 2, которая меньше вашего числа, e.g Если вы начинаете с x = 10.0, то 2 3 = 8, поэтому показатель равен 3. Показатель смещен на 127, поэтому это означает, что показатель будет представлен как 127 + 3 = 130. Тогда мантисса равна 10.0 / 8 = 1.25. 1 неявно, поэтому нам просто нужно представить 0.25, который является 010 0000 0000 0000 0000 0000, когда выражается как 23-битная дробная величина без знака. Бит знака 0 для положительного. Так мы есть:

    вы можете проверить представление с помощью простой программы C, например

    возьмите номер 172.625.Это число имеет формат Base10.

    преобразовать этот формат в формате base2 Для этого сначала преобразуйте 172 в двоичный формат

    преобразовать 0.625 в двоичный формат

    двоичный формат 172.625=10101100.101. Это в формате base2 10101100 * 2

    сдвиг этого двоичного числа

    добавить показатель 127 7+127=134

    преобразовать 134 в двоичный формат

    число является положительным, поэтому знак числа 0

    объяснение: Высокий порядок бит-это знак числа. число хранится в формате знака величины. Показатель хранится в 8-битном формате поля, смещенном на 127 к показателю Цифра справа от двоичной точки хранится в Нижнем порядке 23 бит. Примечание — — — этот формат является IEEE 32-битный формат с плавающей запятой

    число с плавающей запятой просто научная нотация. Допустим, я попросил вас выразить окружность Земли в метрах С использованием научной нотации. Вы напишете:

    на показатель это просто: сила десяти здесь. Мантисса-это фактические цифры. И знак, конечно, только положительный или отрицательный. Таким образом, в этом случае показатель равен 7 и мантисса-4.007516 .

    единственное существенное различие между IEEE754 и научной нотацией начальной школы заключается в том, что числа с плавающей запятой находятся в база 2, так что это не раз десять к силе чего-то, это раз два к силе чего-то. Итак, где бы вы написали, скажем, 256 в обычной человеческой научной нотации как:

    2.56×10 2 (мантисса 2.56 и показатель 2),

    1×2 8 — мантисса равна 1, а показатель равен 8.

    Pro Java

    Страницы

    17 апр. 2015 г.

    Примитивные вещественные типы Java — float, double

    Тип Содержит По умолчанию Размер Диапазон Обертки
    вещественное знаковое 0.0 32 bits от 1.4E−45 до 3.4028235E+38 Float
    вещественное знаковое 0.0 64 bits от 4.9E−324 до 1.7976931348623157E+308 Double

    Вещественные числа в Java представлены типами данных float и double. Как показано в таблицах выше, float является 32 битным значением с плавающей точкой, с обычной точностью, а double представляет 64 битное значение с плавающей точкой, с двойной точностью. Количество бит отведенные под представление этих чисел смотрите в таблице выше. Оба типа соответствуют стандарту IEEE 754-1985, который определяет формат чисел и арифметические операции, применимые к этим числам. Но есть и небольшие отличия от этого стандарта. К обычным вещественным числам добавляются еще четыре значения:

    • положительная бесконечность, выражаемая константой POSITIVE_INFINITY и возникающая при переполнении положительного значения, например в результате операции умножения 3.0*6e307 или при делении на нуль;
    • отрицательная бесконечность NEGATIVE_INFINITY, возникающая при переполнении отрицательного значения, например в результате операции умножения -3.0*6e307 или при делении на нуль отрицательного числа;
    • «не число», записываемое константой NaN (Not a Number) и возникающее, например, при умножении нуля на бесконечность.
    • кроме того, стандарт различает положительный и отрицательный нуль, возникающий при делении на бесконечность соответствующего знака, хотя сравнение 0.0 == -0.0 дает в результате истину, true.

    Операции с бесконечностями выполняются по обычным математическим правилам. Во всем остальном вещественные типы — это обычные вещественные значения, к которым применимы все арифметические операции и операции сравнения.

    Вещественные литералы


    Значения с плавающей точкой можно непосредственно включать в Java программу. В такой величине за необязательной последовательностью цифр следует десятичная точка и другая последовательность цифр. Ниже представлены несколько примеров:

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

    1.2345E02 // 1.2345 × 10 2 , или 123.45
    1e-6 // 1 × 10 -6 , или 0.000001
    6.02e23 // Число Авогадро: 6.02 × 10 23

    Так же с Java 6, возможно записывать в шестнадцатеричном формате:

    0xFp2 // 15×2 2 =60

    Литералы с плавающей точкой по умолчанию являются значениями типа double . При включении значения типа float в программу за числом следует поставить символ f или F :

    double d = 6.02E23;
    float f = 6.02e23f;

    В принципе литералы типа double можно тоже обозначать суффиксом d или D, но это особо не имеет смысла, так как вещественные литералы всегда по умолчанию double .

    Большинство вещественных чисел, по самой их природе, нельзя точно представить каким-либо конечным количеством битов. Таким образом, необходимо помнить, что значения float и double являются только приближенными значениями представляемых ими чисел. float – это 32 битное приближение, которое дает как минимум 6 значимых десятичных разрядов, а double – это 64 битное приближение, которое представляет по крайней мере 15 значимых десятичных разрядов. На практике эти числа подходят для большинства вычислений с вещественными числами.

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

    Бесконечные значения с плавающей точкой ведут себя вполне логично. Например, прибавление к бесконечности или вычитание из нее любого конечного значения дает бесконечность. Поведение отрицательного нуля почти не отличается от положитель ного нуля; фактически оператор равенства == сообщает о равенстве отрицательного и положительного нуля. Единственный способ отличить отрицательный нуль от по ложительного или обычного нуля – разделить на него какоелибо число. 1.0/0.0 дает положительную бесконечность, а деление 1.0 на отрицательный нуль дает отрицательную бесконечность. И наконец, поскольку NaN не является числом, оператор == сообщает, что это значение не равно ни одному другому числу, включая само значение ! Чтобы проверить, являются ли значения float и double нечисловыми (NaN), следует вызвать методы Float.isNaN() и Double.isNaN() .

    Арифметические операции

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

    если в операции один операнд имеет тип double, то и другой приводится к типу double;

    иначе, если один операнд имеет тип float, то и другой приводится к типу float;

    в противном случае действует правило приведения целых значений.

    Побитовые операции с вещественными типами не поддерживаются .

    Операция деление по модулю (или остаток) определяется так же как и для целочисленных типов:
    a % b = a — (a / b) * b

    Так же для операции деления по модулю справедливо следующее выражение:

    a = ((long)(a/b))*b+(a%b)

    Вычисления чисел с плавающей точкой на одном и том же, а тем более на разных процессорах могут давать несколько разные результаты, поскольку виртуальная машина java выполняет эти операции на сопроцессоре (FPU), если он присутствует на устройстве. А в сопроцессоре обычно регистры для работы с плавающей точкой 80 бит, что шире даже чем double. Поэтому, если в эти регистры положить числа double, а потом опять вернуть их в double, то результаты могут быть разные для одинаковых чисел, по умолчанию java эту проблему не решает, то есть нет гарантии, что написанный код работающий с целочисленными типами будет давать одинаковый результат на разных процессорах. Это сделано потому, что желательно использовать сопроцессор для скорости вычислений. Результаты в этом случае могут немного различаться.

    Чтобы результаты были на всех процессорах одинаковые, то следует использовать ключевое слово strictfp в декларации метода, например:

    public static strictfp void main(String[] args)

    В данном случае все что будет происходить в методе main, будет происходить без участия сопроцессора, будет строго округляться в пределах 64 бит и результат будет одинаковым на разных процессорах.

    IEEE 754 с двойной точностью числа от MIPS C до преобразования Java

    У меня есть PIC32 встроенный микроконтроллер работает компилятор C32. Я посылаю UDP пакет, содержащий 64-битное двойное значение в программе Java. В моем тесте, я пытаюсь отправить десятичное значение 40,5 на Java.

    Я бы ожидать, чтобы получить: 0x4044400000000000

    так как System.out.println (Double.longBitsToDouble (0x4044400000000000L));

    Если я посылаю UDP-пакет без каких-либо преобразований, я получаю: 0x00002242352D3330

    Любая идея, как я могу получить это значение в Java? Я не могу сделать головы или хвосты представления C32 двойника.

    PIC32 мало младшему. double Представлено 64 бит, и long составляет 32 бит. Для 64 бит, вам нужно long long .

    htonl() занимает long , как было отмечено выше. Вы его обрезание с броском, и после преобразования порядка байт, вы получаете показанные результаты.

    Я нашел это в Pastebin ; это макрос , который должен работать для конвертирования 64 бита long long :

    Числовые типы данных и операции

    Ключевой момент: Java имеет шесть типов для целых числе и числе с плавающей запятой с операторами +, -, *, / и %.

    1. Числовые типы

    Каждый тип данных имеет диапазон значений. Компилятор выделяет пространство памяти для каждой переменной или константы в соответствии с её типом данных. Java предоставляет восемь примитивных типов данных для числовых значений, символов и логических значений. В этом разделе представлены числовые типы данных и операторы.

    В таблице перечислены шесть числовых типов данных, их диапазоны и размеры их хранения.

    Отрицательный диапазон: от -3.4028235E + 38 до -1.4E — 45

    Положительный диапазон: от 1.4E — 45 до 3.4028235E + 38

    Отрицательный диапазон: от -1.7976931348623157E + 308 до -4.9E — 324


    Положительный диапазон: от 4.9E — 324 до 1.7976931348623157E + 308

    Имя (тип) Диапазон Размер хранения
    byte от -2 7 до 2 7 — 1 (от -128 до 127) 8-бит со знаком
    short от -2 15 до 2 15 — 1 (от -32768 до 32767) 16-бит со знаком
    int от -2 31 до 2 31 — 1 (от -2147483648 до 2147483647) 32-бита со знаком
    long от -2 63 до 2 63 — 1 (т.е., от -9223372036854775808 до 9223372036854775807) 64-бита со знаком
    float 32-бита IEEE 754
    double 64-бита IEEE 754

    Примечание: IEEE 754 является стандартом, утвержденным Институтом инженеров по электротехнике и электронике для представления на компьютерах чисел с плавающей запятой. Стандарт широко принят. Java использует 32-разрядный IEEE 754 для типа float и 64-разрядный IEEE 754 для типа double. Стандарт IEEE 754 также определяет специальные значения с плавающей запятой, которые перечислены в Приложении E.

    Целочисленные типы

    Java использует четыре типа целых чисел: byte, short, int и long. Выбирайте тип, который больше всего подходит для вашей переменной. Например, если вы знаете, что целое число, хранимое в переменной, находится в диапазоне байта, объявите переменную как byte. Для простоты и последовательности, большую часть времени на этом сайте мы будем использовать для целых чисел тип int.

    Типы с плавающей запятой

    Java использует два типа чисел с плавающей запятой: float и double. Тип double в два раза больше чем float. Поэтому double известен как число с двойной точностью, а float – как число с одинарной точностью. Обычно вам следует использовать тип double, поскольку он более точен чем тип float.

    2. Считывание чисел с клавиатуры

    Вы знаете как использовать метод nextDouble() из класса Scanner для считывания значения double с клавиатуры. Вы также можете использовать методы, представленные в следующей таблице, для чтения чисел типов byte, short, int, long и float:

    Метод Описание
    nextByte() прочитать число типа byte
    nextShort() прочитать число типа short
    nextInt() прочитать число типа int
    nextLong() прочитать число типа long
    nextFloat() прочитать число типа float
    nextDouble() прочитать число типа double

    Далее примеры для чтения данных различного типа с клавиатуры:

    Если вы введёте значение из некорректного диапазона или формата, случиться ошибка выполнения. Например, в строке 3 вы введёте 128, произойдёт ошибка, поскольку 128 находится вне диапазона чисел типа byte.

    3. Числовые операторы

    Операторы +, -, *, /, % и операнды

    Операторы для числовых типов данных включают стандартные арифметические операторы: сложение (+), вычитание (), умножение (*), деление (/) и остаток от деления (%).

    Имя Значение Пример Результат
    + Сложение 34 + 1 35
    Вычитание 34.0 — 0.1 33.9
    * Умножение 300 * 30 9000
    / Деление 1.0 / 2.0 0.5
    % Остаток от деления 20 % 3 2

    Целочисленное деление

    Когда оба операнда деления (делимое и делитель) являются целыми числами, результатом деление будет частное без дробной части. Например, 5 / 2 даёт 2, а не 2.5, а -5 / 2 даёт -2, а не -2.5. Для выполнения деления с плавающей точкой один из операндов должен быть числом с плавающей запятой. Например, 5.0 / 2 даёт 2.5.

    Оператор %, известный как остаток от деления, или оператор модуля, даёт остаток после деления. Операндом слева – это делимое, а операнд справа – делитель. Поэтому 7 % 3 даёт 1, 3 % 7 даёт 3, 12 % 4 даёт , 26 % 8 даёт 2 и 20 % 13 даёт 7.

    Оператор % часто используется для положительных целых чисел, но также может использоваться для отрицательных и значений с плавающей запятой. Остаток от деления является отрицательным только если отрицательным является делимое. Например, -7 % 3 даёт -1, -12 % 4 даёт , -26 % -8 даёт -2 и 20 % -13 даёт 7.

    Остаток от деления очень полезен в программировании. Например, чётные числа % 2 всегда , а нечётные числа % 2 всегда 1. Так вы можете использовать это свойство для определения, является ли число чётным или нечётным. Если сегодня суббота, то суббота снова будет через 7 дней. Предположим, вы и ваши друзья собираетесь встретиться через 10 дней. Какой день будет через 10 дней? Вы можете узнать, что будет вторник используя следующее выражение:

    Следующая программа считает сколько минут и секунд содержится в количестве введённых секунд. Например, 500 секунд содержат 8 минут и 20 секунд.

    Метод nextInt() (строка 8) считывает число для seconds. Строка 10 получает минуты используя seconds / 60. Строка 11 (seconds % 60) получает оставшиеся секунды без минут.

    Унарные и бинарные операторы

    Операторы + и могут быть как унарными, так и бинарными. Унарный оператор имеет только один операнд; а бинарные – два. Например, оператор в -5 – это унарный оператор, показывающей, что число 5 является отрицательным, в то время как оператор в 4 — 5 является бинарным оператор для вычитания 5 из 4.

    4. Операции возведения в степень

    Метод Math.pow(a, b) может использоваться для вычисления a b . Метод pow определён в классе Math в Java API. Этот метод вызывается с использованием синтаксиса Math.pow(a, b) (например, Math.pow(2, 3)), который возвращает результата a b (2 3 ). Здесь a и b являются параметрами для метода pow, а числа 2 и 3 настоящими значениями, используемыми для вызова метода. Например:

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

    Работа с числами в языке Java

    4.3. Двоичное представление вещественных чисел

    Двоичные дроби

    Целое число можно представить в виде

    Аналогично можно записать двоичную дробь:

    Заметим, что сдвиг двоичной точки на n разрядов вправо (чаще говорят о сдвиге самого числа влево) эквивалентен умножению числа на . Сдвиг точки влево (то есть сдвиг самого числа вправо) – делению на .

    Мантисса и порядок числа

    Рассмотрим сначала упрощенную схему хранения чисел в формате с плавающей точкой ( floating point ), несколько отличающуюся от реальной.

    Число с плавающей точкой может быть представлено в виде . Множитель s – знак числа. Второй множитель m называется мантиссой, а число – порядком числа.

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

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

    Число сдвигов двоичной точки (с учетом знака) хранится в части ячейки, выделяемой под порядок числа. В нашем примере числа , и будут иметь порядки 0, 1 и -1, соответственно. При перемножении чисел их мантиссы перемножаются, а порядки складываются. При делении – мантиссы делятся, а порядки вычитаются. И умножение, и деление мантисс происходит по тем же алгоритмам, что и для целых чисел. Но при выходе за размеры ячейки отбрасываются не старшие, а младшие биты. В результате каждая операция умножения или деления дает результат, отличающийся от точного на несколько значений младшего бита мантиссы . Аналогичная ситуация с потерей младших бит возникает при умножениях и делениях. Ведь если в ячейках для чисел данного типа хранится значащих цифр числа, то при умножении двух чисел точный результат будет иметь значащих цифр, последние из которых при записи результата в ячейку будут отброшены даже в том случае, если они сохранялись при вычислениях. А при делении в общем случае при точных вычислениях должна получаться бесконечная периодическая двоичная дробь, так что даже теоретически невозможно провести эти вычисления без округлений. С этим связана конечная точность вычислений на компьютерах при использовании формата с «плавающей точкой». При этом чем больше двоичных разрядов выделяется под мантиссу числа, тем меньше погрешность в такого рода операциях.

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

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

    сложим числа и Для первого числа мантисса , порядок 1, так как . Для второго – мантисса порядок -1, так как . Приводим порядок второго числа к значению 1, сдвигая мантиссу на 2 места вправо, так как разница порядков равна 2:

    Но при таком сдвиге теряется два последних значащих бита мантиссы (напомним, хранится 5 бит), поэтому получаем приближенное значение . Из-за чего в машинной арифметике получается


    вместо точного значения .

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

    Научная нотация записи вещественных чисел

    При записи программы в текстовом файле или выдачи результатов в виде «плоского текста» ( plain text ) невозможна запись выражений типа . В этом случае используется так называемая научная нотация, когда вместо основания 10 пишется латинская буква E (сокращение от Exponent – экспонента). Таким образом, запишется как 1.5E14, а как 0.31E-7. Первоначально буква E писалась заглавной, что не вызывало проблем. Однако с появлением возможности набора текста программы в нижнем регистре стали использовать строчную букву e, которая в математике используется для обозначения основания натуральных логарифмов . Запись вида легко воспринять как , а не . Поэтому лучше использовать заглавную букву.

    Литерные константы для вещественных типов по умолчанию имеют тип double . Например, 1.5 , -17E2 , 0.0 . Если требуется ввести литерную константу типа float , после записи числа добавляют постфикс f (сокращение от «float»): 1.5f , -17E2f , 0.0f .

    Минимальное по модулю не равное нулю и максимальное значение типа float можно получить с помощью констант

    • Float.MIN_VALUE — равна
    • Float.MAX_VALUE — равна

    Аналогичные значения для типа double — с помощью констант

    • Double.MIN_VALUE — равна
    • Double.MAX_VALUE — равна .

    Стандарт IEEE 754 представления чисел в формате с плавающей точкой*

    *Этот параграф является необязательным и приводится в справочных целях

    В каком виде на самом деле хранятся числа в формате с плавающей точкой? Ответ дает стандарт IEEE 754 (другой вариант названия IEC 60559:1989), разработанный для электронных счетных устройств. В этом стандарте предусмотрены три типа чисел в формате с плавающей точкой, с которыми могут работать процессоры: real*4 , real*8 и real*10 . Эти числа занимают 4, 8 и 10 байт, соответственно. В Java типу real*4 соответствует float , а типу real*8 соответствует double . Тип real*10 из распространенных языков программирования используется только в диалектах языка PASCAL, в Java он не применяется.

    Число представляется в виде произведения знака , мантиссы и экспоненты :

    Число называется порядком. Оно может меняться для разных чисел. Значение , называемое сдвигом порядка, постоянное для всех чисел заданного типа. Оно примерно равно половине максимального числа , которое можно закодировать битами порядка. Точнее, .

    • Для чисел real*4 : , d= 127.
    • Для чисел real*8 : , d= 1023.
    • Для чисел real*10 : , d=16383.

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

    Согласно стандарту IEEE 754 все числа формата с плавающей точкой при значениях порядка в диапазоне от 1 до хранятся в нормализованном виде. Такое представление чисел будем называть базовым. Когда порядок равен 0, применяется несколько другой формат хранения чисел. Будем называть его особым. Порядок резервируется для кодировки нечисловых значений, соответствующее представление будем называть нечисловым. Об особом и нечисловом представлениях чисел будет сказано чуть позже.

    Размещение чисел в ячейках памяти такое:

    Таблица 4.11.
    Тип Байт1 Байт2 Байт3 Байт4 Байт8 Байт9 Байт10
    real*4 sppp pppp pmmm mmmm mmmm mmmm mmmm mmmm
    real*8 sppp pppp pppp mmmm mmmm mmmm mmmm mmmm mmmm mmmm
    real*10 sppp pppp pppp pppp 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm

    Буква s обозначает знаковый бит ; p – биты двоичного представления порядка, m – биты двоичного представления мантиссы . Если знаковый бит равен нулю, число положительное, если равен единице – отрицательное. В числах real*4 ( float ) и real*8 ( double ) при базовом представлении ведущая единица мантиссы подразумевается, но не хранится, поэтому реально можно считать, что у них под мантиссу отведено не 23 и 52 бита, которые реально хранятся, а 24 и 53 бита. В числах real*10 ведущая единица мантиссы реально хранятся, и мантисса занимает 64 бит. Под порядок в числах real*4 отведено 8 бит, в числах real*8 отведено 11 бит, а в числах real*10 отведено 15 бит.

    Таблица 4.12.
    Тип IEEE 754 Тип Java Число бит мантиссы Число бит порядка Сдвиг порядка
    real*4 float 23+ подразумевается 1 ведущий бит 8 127
    real*8 double 52+ подразумевается 1 ведущий бит 11 1023
    real*10 64 15 16383

    Чему равны минимальное и максимальное по модулю числа при их базовом представлении?

    Минимальное значение достигается при минимальном порядке и всех нулевых битах мантиссы (за исключением ведущего), то есть при m=1 и p=1 . Значит, минимальное значение равно .

    Максимальное значение достигается при максимальном порядке и всех единичных битах мантиссы , то есть при и . Значит, максимальное значение примерно равно

    При значениях порядка в диапазоне от 1 до базовое представление позволяет закодировать

    • числа real*4 примерно от 2.350989E-38 до 3.402824E38,
    • числа real*8 примерно от 2.225074E-308 до 1.797693E308,
    • числа real*10 примерно от 3.362103E-4932 до 1.189731E4932.

    В случае, когда порядок равен 0 или , используется особое представление чисел, несколько отличающееся от базового.

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

    Минимальное ненулевое значение мантиссы в особом представлении равно , где n – число бит мантиссы после двоичной точки.


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

    Таким образом, особое представление позволяет закодировать

    • числа real*4 примерно от 1.401298E-45 до 2.350989E-38,
    • числа real*8 примерно от 4.940656E-324 до 2.225074E-308,
    • числа real*10 примерно от 3.6451995E-4951 до 3.362103E-4932.

    Специальный случай особого представления – когда и порядок и мантисса равны нулю. Это значение обозначает машинный ноль. В соответствии со стандартом IEEE 754 имеются +0 и -0. Но во всех известных автору языках программирования +0 и -0 при вводе-выводе и сравнении чисел отождествляются.

    Нечисловое представление соответствует случаю, когда , то есть все биты порядка равны 1. Такое «число» в зависимости от значения мантиссы обозначает одно из трех специальных нечисловых значений, которые обозначают как Inf ( Infinity — «бесконечность»), NaN (Not a Number — «не число»), Ind ( Indeterminate – «неопределенность»). Эти значения появляются при переполнениях и неопределенностях в вычислениях. Например, при делении 1 на 0 получается Inf , а при делении 0 на 0 получается Ind . Значение NaN может получаться при преобразовании строки в число, взятии логарифма от отрицательного числа, тригонометрической функции от бесконечности и т.п.

    Значение Inf соответствует нулевым битам мантиссы .Согласно IEEE 754 бесконечность имеет знак. Если знаковый бит 0 это + Inf , если знаковый бит 1 это –Inf .

    Значение Ind кодируется единицей в знаковом бите и битами мантиссы , равными 0 во всех разрядах кроме старшего (реального, а не подразумеваемого), где стоит 1. Все остальные сочетания знакового бита и мантиссы отведены под величины NaN . Значения NaN бывают двух типов – вызывающие возбуждение сигнала о переполнении ( Signaling NaN ) и не вызывающие ( Quiet NaN ). Значения обоих этих типов могут быть «положительными» ( знаковый бит равен нулю) и «отрицательными» ( знаковый бит равен единице).

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

    Но значение Ind вообще не употребляется и отождествляется с NaN , хотя Float. NaN и Double. NaN различаются.

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

    Ieee754 — Числа в формате IEEE754 на JAVA

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

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

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

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


      Полное название стандарта в ассоциации IEEE:
    • IEEE Standard for Binary Floating-Point Arithmetic (ANSI/IEEE Std 754-1985)
    • IEEE стандарт для двоичной арифметики с плавающей точкой (ANSI/IEEE Std 754-1985)


      Название стандарта в международной электротехнической комиссии IEC:
    • IEC 60559:1989, Binary floating-point arithmetic for microprocessor systems
    • IEC 60559:1989 двоичная арифметика с плавающей точкой для микропроцессорных систем
    • (IEC 559:1989 — старое обозначение стандарта)

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

    В настоящее время ассоциация IEEE представляет собой коммерческое предприятие, а не общественную ассоциацию инженеров от электроники. IEEE продает информацию по своим документам. Заплатив 77$(цены на март 2009 г.) вы получите документ описывающий стандарт ANSI/IEEE Std 754-1985 в .pdf формате. Описание которое вы получите от IEEE скорее всего только запутает вас, так как широкое использование получила только часть стандарта, остальная часть стандарта малоприменима в технике и программировании и усложняет целостное логическое описание стандарта. Я бесплатно, но доступно опишу Вам применяемую часть стандарта IEEE754. Но если Вы считаете, что бесплатная информация бесполезна, то можете перечислить любую сумму на электронный кошелёк ресурса www.softelectro.ru. Эти пожертвования пойдут на развитие этого некоммерческого ресурса (в частности на описание других стандартов:-)

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



      Стандарт IEEE 754-1985 определят:
    • как представлять нормализованные положительные и отрицательные числа с плавающей точкой
    • как представлять денормализованные положительные и отрицательные числа с плавающей точкой
    • как представлять нулевые числа
    • как представлять специальную величину бесконечность (Infiniti)
    • как представлять специальную величину «Не число» (NaN или NaNs)
    • четыре режима округления
    • пять исключений


      IEEE 753-1985 определяет четыре формата представления чисел с плавающей запятой:
    • с одинарной точностью (single-precision) 32 бита
    • с двойной точностью (double-precision) 64 бита
    • с одинарной расширенной точностью (single-extended precision) >=43 бит (редко используемый)
    • с двойной расширенной точностью (double-extended precision) >= 79 бит (обычно используют 80 бит)

    Основное применение в технике и программирование получили форматы 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 бит 0 1000 0110 001 1011 1010 0000 0000 0000 = 43 1B A0 00 (hex) 0(dec) 134(dec) 1810432(dec) знак числа + смещенная экспонента остаток от мантиссы число 155.625 в формате IEEE754

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

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


      где:
    • S- бит знака (31 бит)
    • E- смещенная экспонента (23-30 биты)
    • M — остаток от мантиссы (0-22 биты)
    • F- десятичное число с плавающей точкой

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

    Вывод этой формулы приводить не буду, всё видно и так. Поясню только (1+ M/2^23) — это мантисса, единица в этой формуле- это та единица, которую мы выбросили из 23 бит, а остаток мантиссы в десятичном виде находим отношением двух целых чисел — остатка мантиссы к целому)

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

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


      где:
    • S — бит числа S=0 — положительное число; S=1 — отрицательное число
    • E — смещенная экспонента; exp = E — 2^(b-1) + 1 , где
      exp — экспонента двоичного нормализованного числа с плавающей точкой
      2^(b-1)-1 — смещение экспоненты
    • M — остаток мантиссы двоичного нормализованного числа с плавающей точкой

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

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

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

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



      Если применить формулу 1 для вычисления минимального и максимального числа представленного в IEEE754, то получим следующие результаты:
    • 00 00 00 00 hex= 5,87747175411144e-39 (минимальное положительное число)
    • 80 00 00 00 hex=-5,87747175411144e-39 (минимальное отрицательное число)
    • 7f ff ff ff hex= 6,80564693277058e+38 (максимальное положительное число)
    • ff ff ff ff hex=-6,80564693277058e+38 (максимальное отрицательное число)

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

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

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

    число IEEE754=80 00 00 00hex считается числом -0
    Рис.5

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

    число IEEE754=FF 80 00 00hex считается числом -∞
    Рис.7

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

    4. числа IEEE754=(x000) (0000) (0xxx)X XX XXhex считаются денормализованными числами, за исключением чисел п.1 , то есть -0 и +0
    Рис.9

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


      Пояснения к исключительным числам:
    • С нулем понятно. Без него никак нельзя. Смущает только наличие двух нулей. Думаю, это было сделано для симметричности.
    • — ∞/ +∞ , тоже понятно. Числа, которые больше границ диапазона представления чисел считаются бесконечными.
    • Не числа NAN(No a Numbers). К ним относятся символы, или результаты недопустимых операций.
    • Денормализованные числа. Это числа, мантиссы которых лежат в диапазоне 0.1 Рис.10

    Рис. 11 Максимальное денормализованое число (абсолютное)
    00 7F FF FF = 2^-126*(1-2^-23) = 1,17549421e-38
    80 7F FF FF = -2^-126*(1-2^-23) =-1,17549421e-38
    Рис.11
    Из рис. 10 и 11 видно что минимальное нормализированное число граничит с максимальным денормализированным.

    Рис. 12 Минимальное денормализованное число (абсолютное)
    00 00 00 01 = 2^-126* 2^-23= 2^-149 = 1,40129846e-45
    80 00 00 01 = -2^-126* 2^-23= 2^-149 = — 1,40129846e-45
    Рис.12
    Это число граничит с нулем.

    Рис.13 Максимальное нормализированное число (абсолютное)
    7F 7F FF FF = 2^127*(2-2^-23) = 3,40282347e+38
    FF 7F FF FF = -2^127*(2-2^-23)= — 3,40282347e+38
    Рис.13
    Это число граничит с бесконечностью.

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

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

    Таблица 1. Сведенья о формате 32/64 бит в стандарте ANSI/IEEE Std 754-1985
    наименование формата single double
    длина числа, бит 32 64
    смещенная экспонента (E), бит 8 11
    остаток от мантиссы (M), бит 23 52
    смещение 127 1023
    формула расчета денормализованых чисел F =(-1)^S*2^(E -126)* M/2^23 F =(-1)^S*2^(E -1022)*M/2^52
    формула расчета нормализованных чисел F =(-1)^S*2^(E-127)*(1+ M/2^23) F =(-1)^S*2^(E-1023)*(1+M/2^52)
    минимальное число ±2^-149=±1,40129846e-45 ±2^-1074= ± 4,94065646e-324
    максимальное число ±2^127*(2-2^-23) = ± 3,40282347e+38 ±2^1023*(2-2^-52) = ± 1,79769313e+308

    Заключение.

    Стандарт 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
    Здесь вы видите не только не точный результат, но и зависимость результата от расположения переменных. Это только одна операция, представьте, что операций тысячи. Результат таких вычислений будет не предсказуем.

    Вот ещё пример: Text1.Text = (c / a — 1) * 10000000000
    Если посчитать на бумажке ответ будет = 0, а если на компьютере = 397,364299242753
    Как Вы считаете- есть ли разница между 0 и 397 (допустим в ядерных бомбах!)

    Цукерберг рекомендует:  Концепция дизайна персональной страницы разработчикадизайнера
    Понравилась статья? Поделиться с друзьями:
    Все языки программирования для начинающих