Скачиваний:
67
Добавлен:
24.03.2015
Размер:
169.98 Кб
Скачать

Глава 4. Выражения с операндами базовых типов

4.1. Автоматическое и явное приведение арифметических типов

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

В соответствии со стандартом ANSI/IEEE Std 754-1985 определены два основных формата представления в ЭВМ вещественных чисел:

  • одинарная точность - четыре байта;

  • двойная точность - восемь байтов.

В языке С# (точнее в платформе .NET Framework) для этих двух представлений используются данные типов float и double. Возможности представления данных с помощью этих типов таковы:

float – мантисса числа 23 бита, т.е. 7 десятичных знаков;

показатель степени (экспонента) 8 бит, что позволяет представлять значения от 1,5*10-45 до 3,4*1038.

double – мантисса числа 52 бита, т.е. 15-16 десятичных знаков;

показатель степени (экспонента) 11 бит, что позволяет представлять значения от 5*10-324 до 1,7*10308.

Мантисса хранится в двоично-десятичном представлении, экспонента представлена в двоичном виде. Как и для знаковых целых типов один бит в представлении вещественных чисел указывает знак мантиссы.

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

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

Беззнаковые Десятичный Знаковые

Рис. 4.1. Выполняемые автоматически преобразования арифметических типов

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

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

Обратите внимание, что в тип double может быть преобразовано значение любого другого арифметического типа корме decimal. В то же время значение типа double не может быть автоматически преобразовано ни к какому другому типу. Распространенная ошибка:

float z=124.3; // недопустимо! - справа значение типа double

Такой инициализации компилятор не допускает, так как по умолчанию (без суффикса F) константа 124.3 имеет тип double.

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

Если один операнд decimal, то второй приводится к типу decimal.

Если один операнд double - второй приводится к типу double.

Если один операнд float, то второй приводится к типу float.

Если один операнд ulong - второй приводится к типу ulong.

Если один операнд long- второй приводится к типу long.

Если один операнд unit - а второй sbyte или short или int, то оба операнда приводятся к типу long.

Если один операнд unit, то второй приводится к типу unit.

Иначе оба операнда приводятся к типу int.

Исключение: Если один операнд ulong, а второй sbyte или short или int или long , то фиксируется ошибка компиляции.

Важным является правило приведения обоих операндов к типу int, если в выражении нет операнда типа decimal, double, float, ulong, long. Об этом мы уже говорили в 3.7, приведя пример с операндами типа short.

В соответствии с этим правилом ошибочной будет последовательность операторов:

short dd, n=24;

sbyte bb=-11;

dd=nn*bb; //ошибка компиляции!

В данном примере при вычислении выражения nn*bb оба операнда переводятся к типу int и результат умножения - значение типа int. Присваивание недопустимо - автоматическое приведение типа int к типу short невозможно (см. рис. 4.1).

Для правильного выполнения необходимо в этом случае явное приведение типов. Выражение с операцией явного приведения типов имеет вид:

(тип) операнд.

Здесь тип - наименование того типа, который должно получить значение операнда.

В нашем примере правильным будет оператор:

dd=(short) (nn*bb);

Обратите внимание, что операция явного приведения типов имеет высокий приоритет, и бинарное выражение (nn*bb) необходимо поместить в скобки.

Соседние файлы в папке Lekc_C#