Опубликован: 18.09.2006 | Уровень: специалист | Доступ: свободно | ВУЗ: Московский государственный университет имени М.В.Ломоносова
Лекция 10:

Основные конструкции языков Java и C#

Типы чисел с плавающей точкой

Представление типов значений с плавающей точкой, float и double, а также операции с ними, соответствуют стандарту на вычисления с плавающей точкой IEEE 754 (он же — IEC 60559) [11,12]. Согласно этому стандарту, значение такого типа состоит из знакового бита, мантиссы и экспоненты (у значения float 23 бита отводятся на мантиссу и 8, на экспоненту, у double52 бита на мантиссу и 11 — на экспоненту).

Помимо обычных чисел, значения обоих типов включают -0.0 (кстати, написав так, вы получите обычный 0.0, поскольку этот текст будет воспринят как константа 0.0, к которой применен унарный оператор -; единственный способ получить -0.0 — конвертировать его битовое представление — в шестнадцатеричном виде для типа float он представляется как 0x80000000, а для double0x8000000000000000 ), положительные и отрицательные бесконечности (для типа float это 0x7f800000 и 0xff800000, а для double0x7ff0000000000000 и 0xfff0000000000000 ), а также специальное значение NaN ( Not-A-Number, не число ; оно может быть представлено любыми значениями, у которых экспонента максимальна, а мантисса не равна 0 ).

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

  • ==, != — сравнения на равенство и неравенство. В соответствии с IEEE 754 NaN не равно ни одному числу, в том числе самому себе. -0.0 считается равным 0.0.
  • <, <=, >, >= — сравнения на основе порядка. +∞ больше, чем любой обычное число и -∞, а -∞ меньше любого конечного числа. NaN несравнимо ни с одним числом, даже с самим собой — это значит, что любая указанная операция возвращает false, если один из ее операндов — NaN. -0.0 считается равным, а не меньше, чем 0.0.
  • +, -, *, /, % — сложение, вычитание, умножение, деление, взятие остатка по модулю, а также соответствующие операции присваивания с одновременным выполнением одного из этих действий. Все эти операции действуют согласно IEEE 754, кроме операции вычисления остатка, которая реализована так, чтобы при всех конечных a и b (b != 0) выполнялось a%b == a – b*n, где n — самое большое по абсолютной величине целое число, не превосходящее |a/b|, знак которого совпадает со знаком a/b. По абсолютной величине a%b всегда меньше b, знак a%b совпадает со знаком a.

    Согласно стандарту IEEE 754, все арифметические операции определены для бесконечных аргументов "естественным" образом: 1.0/0.0 дает +∞ -1.0/0.0 дает -∞, 0.0/0.0NaN, конечное x в сумме с +∞ дает +∞, а +∞+(-∞)NaN. Если один из операндов NaN, то результат операции тоже NaN.

  • ++, -- — увеличение и уменьшение на единицу. Для бесконечностей и NaN результат применения этих операторов совпадает с операндом.

В Java в классах java.lang.Float и java.lang.Double есть константы, равные максимальному конечному значению типа, минимальному положительному значению типа, положительной и отрицательной бесконечностям и NaN.

Float.MAX_VALUE = (2-2-23)•2127
Float.MIN_VALUE = 2-149
Double.MAX_VALUE = (2-2-59)•21023
Double.MIN_VALUE = 2-1074

Бесконечности и NaN в обоих случаях называются POSITIVE_INFINITY, NEGATIVE_INFINITY и NaN.

В C# соответствующие классы System.Single и System.Double также хранят эти значения в виде констант MaxValue, Epsilon, PositiveInfinity, NegativeInfinity и NaN.

В C# есть еще один тип для представления чисел с плавающей точкой — decimal (тип-обертка для него называется System.Decimal ).

Значения этого типа представляются 128 битами, из которых один используется для знака, 96 — для двоичной мантиссы, еще 5 — для представления десятичной экспоненты, лежащей от 0 до 28. Остальные биты не используются.

Представляемое знаком s ( +1 или -1 ), мантиссой m ( 0–(296-1) ) и экспонентой e (0–28) значение равно (-1)s•m•10-e.

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

Для типа decimal определены все те же операции, что и для типов с плавающей точкой, однако при выходе их результатов за рамки значений типа создается исключительная ситуация. Этот тип не имеет специальных значений -0.0, NaN и бесконечностей.

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

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

Владислав Нагорный
Владислав Нагорный

Подскажите, пожалуйста, планируете ли вы возобновление программ высшего образования? Если да, есть ли какие-то примерные сроки?

Спасибо!

Лариса Парфенова
Лариса Парфенова

1) Можно ли экстерном получить второе высшее образование "Программная инженерия" ?

2) Трудоустраиваете ли Вы выпускников?

3) Можно ли с Вашим дипломом поступить в аспирантуру?