Книга Код. Тайный язык информатики, страница 98. Автор книги Чарльз Петцольд

Разделитель для чтения книг в онлайн библиотеке

Онлайн книга «Код. Тайный язык информатики»

Cтраница 98

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

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

1 знаковый бит (s)

8 битов порядка (e)

23 бита дробной значащей части (f)

Итого 32 бита, или четыре байта. Поскольку в значащей части нормализованного двоичного числа с плавающей точкой слева от двоичного разделителя всегда стоит 1, соответствующий ей бит не включается при сохранении числа в формате IEEE. Сохраняется только 23-битная дробная часть. Несмотря на то что для хранения значащей части числа используется только 23 бита, считается, что точность равна 24 битам. Чуть позже мы разберемся в том, что это значит.

Значение 8-битного порядка находится в диапазоне от 0 до 255. Такой порядок называется смещенным. Для нахождения истинного значения порядка с учетом знака необходимо вычесть из него число, называемое смещением. Для чисел одинарной точности с плавающей точкой смещение порядка равно 127.

Значения порядка 0 и 255 используются в особых случаях, о которых расскажу чуть позже. Если значение порядка принадлежит диапазону от 1 до 254, то число, представленное конкретными значениями s (бит знака), e (порядок) и f (дробная часть), равно:

(–1)s × 1,f × 2е − 127.

Выражение (–1)s используется для определения знака числа. Если s равно 0, то число положительное (поскольку любое число в степени 0 равно 1), если s равно 1, то число отрицательное (поскольку –1 в степени 1 равно –1).

Следующая часть выражения 1,f представляет 1, за которой следует двоичный разделитель и 23-битная дробная значащая часть. Все это умножается на 2, возведенное в степень, значением которой является разность хранящегося в памяти 8-битного смещенного порядка и числа 127.

Я не упомянул о способе выражения такого распространенного числа, как 0. Похоже, о нем мы и забыли. Для этого предусмотрено несколько особых случаев:

если e равно 0, f равно 0, то число равно 0; как правило, для представления числа 0 во все 32 бита записываются нули, однако бит знака может быть равен 1, и в этом случае число интерпретируется как отрицательный ноль; бит может обозначать очень маленькое отрицательное число, для представления которого с одинарной точностью доступных цифр и порядков недостаточно;

если e равно 0, а f не равно 0, то число является действительным, но не нормализованным:

(–1)s × 0,f × 2–127;

обратите внимание на 0 слева от двоичного разделителя значащей части;

если e равно 255, а f равно 0, то число символизирует положительную или отрицательную бесконечность — в зависимости от знака s;

если e равно 255, а f не равно 0, то значение считается «не числом» и обозначается аббревиатурой NaN (Not a Number — «не число»); NaN может указывать на неизвестное число или на результат недопустимой математической операции.

Наименьшее нормализованное положительное или отрицательное двоичное число, которое можно представить с одинарной точностью в формате с плавающей точкой, следующее:

1,00000000000000000000000ДВА × 2–126.

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

1,11111111111111111111111ДВА × 2127.

В десятичной системе счисления эти два числа приблизительно равны 1,175494351 × 10–38 и 3,402823466 × 1038. Именно этими числами ограничивается диапазон чисел с плавающей точкой одинарной точности.

Вероятно, вы помните, что десять двоичных цифр примерно эквивалентны трем десятичным цифрам. Под этим подразумеваю, что двоичное число, состоящее из десяти единиц, которое соответствует числу 3FFh в шестнадцатеричном формате и 1023 в десятичном, приблизительно равно числу из трех девяток, то есть 999. Таким образом:

210 ≈ 103.

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

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

Правильнее было бы сказать, что число одинарной точности с плавающей точкой имеет точность до одной части из 224 (одной части из 16 777 216, примерно до шести частей из 100 миллионов). Что это значит на самом деле?

Во-первых, если вы попытаетесь выразить значения 16 777 216 и 16 777 217 в виде чисел одинарной точности с плавающей точкой, они окажутся одинаковыми. Более того, любое число в промежутке между этими двумя значениями (например, 16 777 216,5) тоже будет совпадать с ними. Все три десятичных числа сохраняются в памяти в виде 32-битного числа одинарной точности с плавающей точкой, которое, будучи разделенным на биты знака, порядка и значащей части, выглядит следующим образом.

4B800000h

0 10010111 00000000000000000000000

И оно эквивалентно

1,00000000000000000000000ДВА × 224.

Следующее значение, выраженное двоичным числом с плавающей точкой, эквивалентно числу 16 777 218:

1,00000000000000000000001ДВА × 224.

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

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

1,00000000000000000000000ДВА × 218.

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

Вход
Поиск по сайту
Ищем:
Календарь
Навигация