Поразрядная операциясдвиг вправо имеет некоторые особенности выполнения. По аналогии со сдвигом влево операция сдвига вправо на n разрядов интерпретируется как целочисленное деление на 2n. При этом заполнение освобождающихся старших разрядов производится таким образом, чтобы сдвиг соответствовал операции деления с учетом формы представления целого. Длябеззнакового целого заполнение должно производиться нулями (логический сдвиг), а для целого со знаком - сопровождаться дублированием значения старшего знакового разряда (арифметический сдвиг). В последнем случае отрицательное число при сдвиге останется отрицательным:
short n=0xFF00; n>>= 4; //n=0xFFF0;
unsigned short u=0xFF00; u>>=4; //u=0x0FF0;
Формы представления числовых данных
Целое без знака
Содержимое машинного слова используется для представления целых положительных значений без знака. Каждый разряд машинного слова имеет вес. в два раза больший, чем вес соседнего правого. то есть 1, 2, 4, 8, 16 и т.д., или последовательные степени 2. Тогда значение числа в машинном слове равно сумме произведений значений разрядов на их веса:
|
|
R0 * 1 + R1 * 2 + R2 * 4 +... + R15 * 32768 или
R0 * 20 + R1 * 21 +... + R15 * 215
Например, машинное слово 00000000010001001 имеет значение 1+8+128 = 137. Получить значение восьмеричной или шестнадцатеричной константы в десятичной системе можно также путем умножения цифр числа на веса разрядов - последовательные степени 8 или 16:
0х6DСС =12(С)*160 +12(С)*161 + 13(D)*162 +6*163 =
= 12 * 12*16 + 13*256 + 6*4096
Представление отрицательных чисел
Дополнительный код
Близость языка С++ кархитектуре компьютера позволяют наблюдать, а при необходимости и использовать особенности представления целых чисел со знаком на уровне машинных слов. Идея заключается в том, что область отрицательных отображается на область беззнаковых положительных таким образом, что для них можно использовать часть команд для целых без знака (сложение).
Дополнительный код - беззнаковая форма представления чисел со знаком.
Такой «фокус» может быть произведен в любой системе счисления. Продемонстрируем его в десятичной.
Пусть имеется трехразрядное десятичное число со знаком. Представим его в следующем виде:
· добавим слева еще одну цифру - знак числа, принимающую всего два значения: 0 - плюс, 9 - минус;
· положительные числа представим обычным образом;
· каждую цифру отрицательного числа заменим на дополнение ее до n-1, где n - основание системы счисления. Для десятичной системы - это дополнение до 9, то есть цифра, которая в сумме с исходной дает 9;
·к полученному числу добавим 1.
Такое представление отрицательных чисел называется дополнительным кодом. Он обладает одним замечательным свойством: сложение чисел в дополнительном коде по правилам сложения целых без знака дает корректный результат, который также получается в дополнительном коде.
|
|
- 3 8 6 - отрицательное число
9 6 1 3 - дополнение каждой цифры до 9
9 6 1 4 - добавление 1
Рассмотрим примеры.
Пример 1:
512 – 386 = 0 5 1 2
+ 9 6 1 4
--------
1 0 1 2 6 - для знака используется 0 или 9
0 1 2 6 (переполнение игнорируется)
Пример 2:
119 -386 = 0 1 1 9
+ 9 6 1 4
--------
9 7 3 3 - результат в дополнительном коде
- 2 6 6 - дополнение каждой цифры до 9
- 2 6 7 - добавление 1
Получаем следующий результат: вычитание или сложение чисел со знаком заменяется операцией сложения, выполненной для беззнаковых чисел.
В двоичной системе счисления дополнение каждой цифры до основания системы счисления без единицы (n-1=1) выглядит как инвертирование двоичного разряда. Если же знак числа представляется старшим разрядом машинного слова, то получается простой способ представления отрицательного числа:
1. взять абсолютное значение числа в двоичной системе;
2. инвертировать все разряды, включая знаковый;
3. добавить к результату 1.
Используя поразрядные операции, можно «превратить» положительное число в отрицательное:
int a = 125; a = ~a + 1; // Эквивалентно а=-а;
На самом деле от программиста, даже при работе на уровне внутреннего представления данных, достаточно знать правила отображения диапазонов положительных и отрицательных значений знаковых чисел на диапазон беззнаковых. Используемая форма преобразования приводит к тому, что отрицательные числа отображаются на «вторую половину» диапазона беззнаковых целых, причем таким образом, что значение -1 соответствует максимальному беззнаковому (то есть 0xFFFF во внутреннем представлении), а минимальное отрицательное - середине интервала (то есть 0x8001). Значение 0x8000 является «водоразделом» положительных и отрицательных и называется минус 0. Все отрицательные числа имеют старший (знаковый) бит, установленный в 1.
Целое со знаком | Значение в дополнительном коде |
… | … |
+32766 | 0x7FFE |
+32767 (+MAXINT) | 0x7FFF |
-1 | 0xFFFF |
-2 | 0xFFFE |
-16 | 0xFFF0 |
-32767 (-MAXINT) | 0x8001 |
не определено (минус 0) | 0x8000 |