Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Подбельский Фомин_Программирование на языке СИ_...doc
Скачиваний:
356
Добавлен:
10.08.2019
Размер:
53.81 Mб
Скачать

Правила стандартных арифметических преобразований

Исходный тип

Преобразованный тип

Правила преобразований

char

int

Расширение нулем или знаком в зависимости от умолчания для char

unsigned char

int

Старший байт заполняется нулем

signed char

int

Расширение знаком

short

int

Сохраняется то же значение

unsigned short

unsigned int

Сохраняется то же значение

enum

int

Сохраняется то же значение

битовое поле

int

Сохраняется то же значение

Используя арифметические выражения, следует учитывать приведенные правила и не попадать в "ловушки" преобразования типов, так как некоторые из них приводят к потерям информации, а другие изменяют интерпретацию битового (внутреннего) представления данных.

На рис. 1.2 стрелками отмечены "безопасные" арифметические преобразования, гарантирующие сохранение точности и неизменность численного значения.

Рис. 1.2. Арифметические преобразования типов, гарантирующие сохранение значимости

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

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

Выражения с поразрядными операциями.

Выражения с поразрядными операциями. Поразрядные операции позволяют конструировать выражения, в которых обработка операндов выполняется на битовом уровне (поразрядно). Рассмотрим возможности операций над битами:

~ - поразрядное отрицание (дополнение или инвертирование битов) (ранг 2);

>> - сдвиг вправо последовательности битов (ранг 5);

<< - сдвиг влево последовательности битов (ранг 5);

^ - поразрядное исключающее ИЛИ (ранг 9);

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

& - поразрядное И (поразрядная конъюнкция) (ранг 8).

Операция поразрядного отрицания (дополнения или инвертирования битов) обозначается символом "~" и является унарной (одноместной), т.е. действует на один операнд, который должен быть целого типа. Значение операнда в виде внутреннего битового представления обрабатывается таким образом, что формируется значение той же длины (того же типа), что и операнд. В битовом представлении результата содержатся 1 во всех разрядах, где у операнда 0, и 0 в тех разрядах, где у операнда 1. Например:

Значением F будет восьмеричный код '\076' символа '>' (см. Приложение 1). Действительно, битовые представления значений Е и F можно изобразить так:

11000001 -для значения переменной Е, т.е. для '\0301'

00111110 - для значения переменной F, т.е. для '\076'

За исключением дополнения, все остальные поразрядные операции бинарные (двухместные).

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

5 << 2 будет равно 20

5>> 2 будет равно 1

Битовые представления тех же операций сдвига можно изобразить так:

101 << 2 равно 10100, т.е. 20;

101>> 2 равно 001, т.е. 1.

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

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

При положительном левом операнде сдвиг вправо на N позиций эквивалентен уменьшению значения левого операнда в 2N раз с отбрасыванием дробной части результата. (Поэтому 5»2 равно 1.)

Операция "поразрядное исключающее ИЛИ". Эта операция имеет очень интересные возможности. Она применима к целым операндам. Результат формируется при поразрядной обработке битовых кодов операндов. В тех разрядах, где оба операнда имеют одинаковые двоичные значения (1 и 1 или 0 и 0), результат принимает значение 1. В тех разрядах, где биты операндов не совпадают, результат равен 0. Пример использования:

Переменные а и z "обменялись" значениями без использования вспомогательной переменной!

Поразрядная дизъюнкция (поразрядное ИЛИ) применима к целочисленным операндам. В соответствии с названием она позволяет получить 1 в тех разрядах результата, где не одновременно равны 0 биты обоих операндов. Например:

5|6 равно 7 (для 5-код 101, для 6-код 110);

10 | 8 равно 10 (для 10 - код 1010, для 8 - код 1000).

Поразрядная конъюнкция (поразрядное И) применима к целочисленным операндам. В битовом представлении результата только те биты равны 1, которым соответствуют единичные биты обоих операндов. Примеры:

5&6 равно 4 (для 5 - код 101, для 6 - код 110);

10&8 равно 8 (для 10 - код 1010, для 8 - код 1000).