Представление целых чисел в .NET. Печать
Добавил(а) microsin   

Когда используются побитовые операции (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.