Представление целых чисел в .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); } Например:
Как можно увидеть, используется схема 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. |