Когда используются побитовые операции (bitwise operation) с целыми числами, важно понимать, как числа интегрального типа (integral type) хранятся в памяти.
Следующий код будет генерировать строки для значений Int32, где старший значащий бит MSB (most significant bit) находится слева, т. е. применяется тип хранения под названием big endian:
static string BinaryStringOfUInt32(UInt32 number)
{
char[] s = new char[32];
for (int shiftIndex = 0; shiftIndex < 32; shiftIndex++)
s[32 - shiftIndex - 1] = (number & (1 << shiftIndex)) == 0 ? '0' : '1';
return new string(s);
}
Например:
0 |
|
00000000000000000000000000000000 |
1 |
|
00000000000000000000000000000001 |
-1 |
|
11111111111111111111111111111111 |
2 |
|
00000000000000000000000000000010 |
-2 |
|
11111111111111111111111111111110 |
2^6 (1 << 6) |
|
00000000000000000000000001000000 |
Int32.MinValue (-2147483648) |
|
10000000000000000000000000000000 |
Int32.MaxValue (2147483647) |
|
01111111111111111111111111111111 |
Как можно увидеть, используется схема Two’s Complement [1] (хранение отрицательных чисел по схеме дополнения единицей). В отличие от неё, другая схема Ones’ Complement [2] имеет разные значения для +0 и -0. Когда +0 соответствует числу, у которого все биты сброшены в 0, то у -0 все биты установлены в 1. Для схемы two complements мы имеем следующее соотношение для целых встроенных типов со знаком (signed integral types):
~n = -(n+1)
Здесь ~ является оператором побитной инверсии (bitwise negation). Соотношение сохраняется для минимального и максимального значения, MinValue и MaxValue. К примеру, Int32.MinValue = 1 << 31 и Int32.MaxValue = ~ (1 << 31). Арифметические операции полностью инкапсулированы в процессор (поддерживаются им аппаратно). Дизассемблированный код:
x = x - 1;
000000c7 dec dword ptr [ebp-44h]
У беззнаковых встроенных целых типов (unsigned integral types) нет бита знака. Например, BinaryStringOfUInt32(UInt32.MaxValue) соответствует "1111111111111111111111111111111", BinaryStringOfUInt32(UInt32.MinValue) соответствует "00000000000000000000000000000000".
[Ссылки]
1. Two’s Complement. 2. Ones’ Complement. |