Смекни!
smekni.com

Общие представления о языке Java 5 (стр. 28 из 68)

0.110112 = 0.0110112* (102)1.

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

1.10112*(102)1 + 0.0110112*(102)1 = (1.10112 + 0.0110112)*(102)1 ≈ (1.10112 + 0.01102)*(102)1 =10.00012* (102)1 ≈ 1.00002*(102)2

вместо точного значения 1.00001112*(102)2.

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

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

При записи программы в текстовом файле или выдачи результатов в виде “плоского текста” (plain text) невозможна запись выражений типа

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

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

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

Float.MIN_VALUE - равна 2-149

Float.MAX_VALUE - равна (2-2-23)∙2127

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

Double.MIN_VALUE - равна 2-1074

Double.MAX_VALUE - равна (2-2-52)∙21023.

Стандарт 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 он не применяется.

Число r представляется в виде произведения знака s, мантиссы m и экспоненты 2p-d :

r=s*m*2p-d.

Число p называется порядком. Оно может меняться для разных чисел. Значение d, называемое сдвигом порядка, постоянное для всех чисел заданного типа. Оно примерно равно половине максимального числа pmax, которое можно закодировать битами порядка. Точнее, d= (pmax+1)/2-1.

Для чисел real*4: pmax = 255, d= 127.

Для чисел real*8: pmax = 2047, d= 1023.

Для чисел real*10: pmax =32767, d=16383.

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

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

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

Тип Байт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 бит.

Тип 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. Значит, минимальное значение равно 21-d.

Максимальное значение достигается при максимальном порядке и всех единичных битах мантиссы, то есть при m≈2 и p= pmax-1. Значит, максимальное значение примерно равно

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

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

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

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

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

Минимальное отличное от нуля положительное число для некоторого типа чисел с плавающей точкой равно 21-d-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 при вводе-выводе и сравнении чисел отождествляются.

Нечисловое представление соответствует случаю, когда p=pmax, то есть все биты порядка равны 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 значения бесконечности различаются как по знаку, так и по типу: имеются Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY.