Изменения

Перейти к: навигация, поиск

Представление вещественных чисел

785 байт добавлено, 19:36, 12 января 2015
м
Паршуков, тикет 4-3, 4, 5, 12
Вещественные числа обычно представляются в виде чисел с плавающей запятой. Числа с плавающей запятой — один из возможных способов представления действительных чисел, который является компромиссом между точностью и диапазоном принимаемых значений, его можно считать аналогом экспоненциальной записи чисел, но только в памяти компьютера.
Число с плавающей запятой состоит из набора отдельных двоичных разрядов, условно разделенных на так называемые '''знак''' ('''sign'''), '''порядок''' ('''exponent''') и '''мантиссу''' ('''mantis'''). В наиболее распространённом формате (стандарт IEEE 754) число с плавающей запятой представляется в виде набора битов, часть из которых кодирует собой мантиссу числа, другая часть — показатель степени, и ещё один бит используется для указания знака числа (<tex>0</tex> {{- --}} если число положительное, <tex>1</tex> {{--- }} если число отрицательное). При этом порядок записывается как целое число в [[Представление целых чисел: прямой код, код со сдвигом, дополнительный код|коде со сдвигом]], а мантисса {{--- }} в [[#Нормальная и нормализованная форма|нормализованном виде]], своей дробной частью в двоичной системе счисления. Вот пример такого числа из <tex>16</tex> двоичных разрядов:
{|class="wikitable" style="border-collapse: collapse; border: none"
|-
|}
Знак {{- --}} один бит, указывающий знак всего числа с плавающей точкой. Порядок и мантисса — целые числа, которые вместе со знаком дают представление числа с плавающей запятой в следующем виде:
<tex>(-1)^s S \times M \times B^E</tex>, где s — S {{---}} знак, B{{---}} основание, E {{---}} порядок, а M {{---}} мантисса.Десятичное число, записываемое как <tex> ReE</tex>, где R {{---}} число в интервале [1; 10), E {{---}} степень, в которой стоит множитель <tex>10</tex>;В нормализированной форме модуль R будет являться мантиссой, а E - порядком, а S будет равно <tex>1</tex> тогда и только тогда, когда R < <tex>0</tex>.Например, в числе <tex>-2435e9</tex> * S = <tex>1</tex>* B = <tex>10</tex>* M = <tex>2435</tex>* E = <tex>9</tex>
Порядок также иногда называют '''экспонентой''' или просто '''показателем степени'''.
|colspan=4 style="border: none; border-right: 1px solid gray; text-align: right"|0
|}
Порядок записан [[Представление целых чисел: прямой код, код со сдвигом, дополнительный код|со сдвигом]] '''<tex>-15</tex>'''. То есть чтобы получить актуально значение порядка нужно вычесть из него сдвиг. Сдвиг можно получить по формуле <tex>2^{b-1}-1</tex>, где <tex>b</tex> {{- --}} число бит, отведенное на хранение порядка (в случае числа половинной точности <tex>b=5</tex>).
'''Ограничения точности'''
== Особые значения чисел с плавающей точкой ==
=== Ноль (со знаком) ===
Как уже было оговорено выше, в нормализованной форме числа с плавающей точкой невозможно представить ноль. Поэтому для его представления зарезервированы специальные значения мантиссы и порядка {{- --}} число считается нулём, если все его биты, кроме знакового, равны нулю. При этом в зависимости от значения бита знака ноль может быть как положительным, так и отрицательным.
{|class="wikitable" style="border-collapse: collapse; border: none"
=== Неопределенность (''NaN'') ===
'''NaN''' {{- --}} это аббревиатура от фразы "''not a number''". NaN является результатом арифметических операций, если во время их выполнения произошла ошибка (примеры см. ниже). В IEEE 754 NaN представлен как число, в котором все двоичные разряды порядка {{--- }} единицы, а мантисса не нулевая.
{|class="wikitable" style="border-collapse: collapse; border: none"
=== Бесконечности ===
В число с плавающей запятой можно записать значение <tex>+\infty</tex> или <tex>-\infty</tex>. Как и нули со знаком, бесконечности позволяют получить хотя бы близкий к правильному результат вычисления в случае переполнения. Согласно стандарту IEEE 754 число с плавающей запятой считается равным бесконечности, если все двоичные разряды его порядка {{- --}} единицы, а мантисса равна нулю. Знак бесконечности определяется знаковым битом числа.
{|class="wikitable" style="border-collapse: collapse; border: none"
=== Денормализованные числа ===
'''Денормализованные числа''' (''denormalized/subnormal numbers'') - это способ увеличить количество представимых числом с плавающей запятой значений около нуля, дабы повысить точность вычислений. Каждое значение денормализованного числа меньше самого маленького '''нормализованного''' ("обычного") значения числа с плавающей запятой.
Согласно стандарту, если порядок равен своему минимальному значению (все его биты {{- --}} нули, а истинное значение порядка равно его сдвигу) и все биты мантиссы равны нулю, то это <tex>\pm0</tex>. Если же мантисса не равна нулю, то это число с порядком, на единицу большим минимального (все биты порядка, кроме младшего {{--- }} нули) и данной мантиссой, '''целая часть которой считается равной нулю, а не единице'''.
То есть число с плавающей запятой, при учете вышесказанного, можно задать следующим образом:
* <tex>(-1)^s\times0.M\times2^{E_{min}}</tex>, если <tex>E=E_{min}-1</tex> (''денормализованное число'')
Где <tex>s</tex> {{--- }} бит знака, <tex>M</tex> {{- --}} последовательность битов мантиссы, <tex>E</tex> {{--- }} значение порядка (с учетом сдвига), <tex>E_{min}</tex> {{--- }} минимальное значение порядка, используемое для записи чисел (1{{---}} ''сдвиг'') , <tex>E_{min}-1</tex> {{- --}} минимальное значение порядка, которое он в принципе может принять (все биты нули, 0{{---}} ''сдвиг'').
Хоть денормализованные числа и позволяют бороться с погрешностями и обрабатывать очень маленькие значения, за эти возможности приходится дорого платить. Ввиду сложности денормализованные числа крайне редко реализуют на аппаратном уровне - вместо этого используются программные реализации, работающие значительно медленнее. <br/>
Итак, первое число в машинном 32-разрядном представлении с плавающей точкой будет иметь вид:
<tex>1</tex><strong>10000111</strong><tex>00001101001110000000000</tex> (жирным шрифтом выделен порядок числа, длина мантиссы {{- --}} 23 бита).
Переведем второе число в машинный вид, совершая те же действия.
<tex>1</tex>,<tex>1001010111100</tex><sub><tex>2</tex></sub> - <tex>1</tex>,<tex>0000110100111</tex><sub><tex>2</tex></sub> = <tex>0</tex>,<tex>1000100010101</tex><sub><tex>2</tex></sub>
Приводим полученный результат к машинному виду. Для этого мы должны внести поправку в порядок {{- --}} уменьшить его на единицу. Знак результата {{--- }} положительный, следовательно, бит знака содержит ноль.
<tex>0</tex><strong>10000110</strong><tex>00010001010100000000000</tex>
*[http://en.wikipedia.org/wiki/Floating_point Wikipedia - Floating point]
*[http://en.wikipedia.org/wiki/IEEE_754-2008 Wikipedia - IEEE 754-2008]
*[http://charm.cs.uiuc.edu/papers/SubnormalOSIHPA06.pdf Статья Isaac Dooley, Laxmikant Kale "Quantifying the Interference Caused by Subnormal Floating-Point Values"]
=== Что стоит прочесть ===
* [http://grouper.ieee.org/groups/754 Материалы по стандарту IEEE 754 ''(англ.)'']
* [http://softelectro.ru/ieee754.html Русский перевод стандарта IEEE 754]
 
 
== Примечания ==
[http://charm.cs.uiuc.edu/papers/SubnormalOSIHPA06.pdf Статья Isaac Dooley, Laxmikant Kale "Quantifying the Interference Caused by Subnormal Floating-Point Values"]
[[Категория: Дискретная математика и алгоритмы]]
[[Категория: Представление информации]]

Навигация