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

3.4. Выражения с арифметическими операциями

Кроме операций инкремента и декремента для целочисленных операндов определены, во-первых, стандартные арифметические операции: унарные - и + (определяют знак выражения); бинарные -, +, *, / (вычитание, сложение, умножение, деление).

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

// 03_01.cs - целочисленное деление

static void Main()

{

Console.WriteLine("-13/4 = " + -13 / 4);

Console.WriteLine("15/-4 = " + 15 /-4);

Console.WriteLine("3/5 = " + 3 / 5);

}

Обратите внимание на аргумент метода WriteLine(). Это выражение с операцией конкатенации строк +. Первая строка – изображение некоторого выражения. Вторая строка – строковое представление результата вычисления арифметического выражения, например - 13/4.

Результат выполнения программы:

-13/4 = -3

15/-4 = -3

3/5 = 0

Отдельно следует рассмотреть операцию получения остатка от деления целочисленных операндов %. При ненулевом делителе для целочисленных величин выполняется соотношение:

(х / у * у +х % у) равно х.

Иллюстрация:

// 03_02.cs - получение остатка от деления

static void Main()

{

Console.WriteLine("13 % 4 = " + 13 % 4);

Console.WriteLine("-13 % 4 = " + -13 % 4);

Console.WriteLine("13 % -4 = " + 13 % -4);

Console.WriteLine("-13 % -4 = " + -13 % -4);

Console.WriteLine("-13/-4*-4 + -13%-4 = " +(-13 / -4 * -4 + -13 % -4));

}

Результат выполнения программы:

13 % 4 = 1

-13 % 4 = -1

13 % -4=1

-13 % -4 = -1

13/-4*-4 + -13%-4 = -13

3.5. Поразрядные операции

От языков Си и Си++ язык С# унаследовал операции для работы с битовыми представлениями целых чисел:

~ - поразрядное инвертирование (поразрядное НЕТ); &- поразрядная конъюнкция (поразрядное И);

| - поразрядная дизъюнкция (поразрядное ИЛИ);

^ - взаимоисключающее поразрядное ИЛИ;

>> - поразрядный сдвиг вправо;

<< - поразрядный сдвиг влево.

Таблица 3.1. Правила выполнения поразрядных операций

Значения операндов

Результаты выполнения операции

Первого

Второго

&

|

^

0

0

0

0

0

0

1

0

1

1

1

0

0

1

1

1

1

1

1

0

Для иллюстрации выполнения поразрядных операций удобно использовать операнды беззнакового байтового типа (byte). Рассмотрим вначале поразрядную унарную операцию инвертирования (~). Операция применяется к каждому разряду (биту) внутреннего представления целочисленного операнда. Предположим, что значение переменной bb беззнакового байтового типа равно 3. Внутреннее представление bb имеет вид 00000011. После выполнения операции ~ битовым представлением результата (т.е. выражения ~bb), станет 11111100, то есть 252 при использовании десятичного основания.

Операция &. Определим две байтовых переменных bb со значением 3 и dd со значением 6:

byte bb=3, dd=6;

Поразрядные (битовые) представления: 00000011 и 00000110. Значением выражения bb&dd будет десятичное 2, имеющее внутреннее представление 00000010.

Применив к переменным bb и dd бинарную операцию поразрядной дизъюнкции |, получим десятичное значение 7 с поразрядным представлением 00000111.

Применив бинарную операцию ^ исключающего ИЛИ к переменным bb и dd получим десятичное значение 5 с битовым представлением 00000101.

Следующая программа содержит описанные выше выражения с поразрядными операциями над переменными типа byte.

//03_03.cs - поразрядные операции с беззнаковыми переменными

static void Main03()

{

byte bb = 3;

Console.WriteLine("bb = " + bb + "; ~bb = " + (byte)(~bb));

byte dd = 6;

Console.WriteLine("bb & dd = " + (byte)(bb & dd));

Console.WriteLine("bb | dd = " + (byte)(bb | dd));

Console.WriteLine("bb ^ dd = " + (byte)(bb ^ dd));

}

Поясним еще раз особенности обращений к методу WriteLine(). Аргумент метода должен быть строкового типа (типа string). Выражение вида

строка + арифметическое выражение

обрабатывается так: вычисляется арифметическое выражение, его значение автоматически преобразуется в строку, которая "присоединяется" к строке, размещенной слева от знака +. Чтобы значение арифметического выражения при преобразованиях "не потеряло" свой беззнаковый тип, явно используется операция приведения типов (byte). Необходимость указанного приведения типов будет обоснована в § 3.7. Более подробно приведение типов рассмотрено в следующей главе.

Результаты выполнения программы:

bb = 3; ~bb = 252

bb&dd = 2

bb | dd = 7

bb ^ dd = 5

Бинарные поразрядные операции сдвига (>> и <<) по-разному используют значения своих операндов. Левый операнд задает целочисленное значение, к битовому представлению которого применяется сдвиг. Правый операнд указывает количество разрядов (битов), на которое должны сдвигаться все биты внутреннего представления левого операнда. Направление сдвига зависит от операции: << обозначает сдвиг влево, >> обеспечивает сдвиг вправо.

При сдвиге влево << все разряды, выходящие за левый край внутреннего представления значения левого операнда, отбрасываются, все "освободившиеся" справа позиции заполняются нулями. Таким образом, сдвинув влево на 3 позиции число 4 с двоичным представлением 00000100, получим 00100000 (десятичное 32). Сдвиг влево числа 00010000 (десятичное 16) на 4 позиции приводит к нулевому значению. Обратим внимание, что сдвиг влево на к позиций эквивалентен умножению левого операнда на 2к. (При условии, что значащие левые ненулевые разряды не выйдут за разрядную сетку.) Значением выражения 6<<3 будет десятичное число 48, то есть 6*23 или 00110000.

При сдвиге вправо >> разряды, выходящие за правый край представления значения левого операнда, отбрасываются. Слева "освободившиеся" позиции заполняются нулями. Таким образом, число 25 с двоичным представлением 00011001 при сдвиге на 2 позиции вправо приводит к получению кода 00000110 со значением 6. Сдвиг вправо на к позиций эквивалентен умножению на 2к с округлением результата до целого значения. Выражение 6>>2 будет равно 1, то есть 00000001.

Следующая программа иллюстрирует сказанное относительно поразрядных сдвигов:

//03_04.cs - операции сдвигов для беззнаковых целых

static void Main04()

{

byte bb = 4;

Console.WriteLine("bb = " + bb + ", bb << 3 = " + (byte)(bb << 3));

bb = 16;

Console.WriteLine("bb = " + bb + ", bb << 4 = " + (byte)(bb << 4));

bb = 6;

Console.WriteLine("bb = " + bb + ", bb << 3 = " + (byte)(bb << 3));

bb = 25;

Console.WriteLine("bb = " + bb + ", bb >> 2 = " + (byte)(bb >> 2));

bb = 6;

Console.WriteLine("bb = " + bb + ", bb >> 2 = " + (byte)(bb >> 2));

}

Результат выполнения программы:

bb = 4; bb << 3 = 32

bb = 16; bb << 4 = 0

bb = 6; bb << 3 = 48

bb = 25; bb >> 2 = 6

bb = 6; bb >> 2 = 1

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