A тип данных - это абстракция, которая применяется к фрагменту памяти, чтобы увидеть этот фрагмент памяти как область, которая может представлять значение.
Например, один байт состоит из 8 бит памяти. На следующей диаграмме каждый бит представлен подчеркиванием (_
):
byte: _ _ _ _ _ _ _ _ <- 8 bits
Поскольку у нас есть 8 позиций, в которые мы можем ввести либо 0
, либо 1
(поскольку каждый бит памяти может быть установлен только в состояние on
или off
- следовательно, двоичный ), поэтому мы можем иметь 2^8
или 256 комбинаций различных значений, которые мы можем представить из 8 битов.
Это - то, где понятие диапазона входит в игру - как мы распределяем эти 256 комбинаций значений в пригодный для использования диапазон?
Один из способов - взять первую из 256 комбинаций как 0
, а окончательную комбинацию - 255
:
byte: 0 0 0 0 0 0 0 0 <- Represents a "0"
byte: 0 0 0 0 0 0 0 1 <- Represents a "1"
.. so on ..
byte: 1 1 1 1 1 1 1 0 <- Represents a "254"
byte: 1 1 1 1 1 1 1 1 <- Represents a "255"
Для этого типа данных диапазон составляет от 0
до 255
. Этот тип обычно называется unsigned byte
, поскольку значения, которые он может представлять, равны unsigned
, так как он не имеет знака. По сути, он обрабатывается так, как если бы это были положительные числа.
С другой стороны, поскольку у нас 256 комбинаций, что, если мы назначим половину из них как положительные числа, а другая половина - отрицательные числа? Итак, мы присваиваем положительное или отрицательное значение байтовому представлению:
byte: 0 1 1 1 1 1 1 1 <- Represents a "127"
byte: 0 1 1 1 1 1 1 0 <- Represents a "126"
.. so on ..
byte: 0 0 0 0 0 0 0 1 <- Represents a "0"
byte: 0 0 0 0 0 0 0 0 <- Represents a "0"
byte: 1 1 1 1 1 1 1 1 <- Represents a "-1"
.. so on ..
byte: 1 0 0 0 0 0 0 1 <- Represents a "-127"
byte: 1 0 0 0 0 0 0 0 <- Represents a "-128"
Вышеупомянутое представление называется системой «два дополнения», а таблица выше была адаптирована из статьи Википедии о дополнении двоих .
При таком типе представления в одних и тех же 8 битах мы можем определить способ представления диапазона чисел от -128
до 127
. Это представление обычно называется signed byte
, потому что это тип byte
, который может иметь как положительные, так и отрицательные представления числа.
При сравнении unsigned byte
и signed byte
их диапазоны различны:
unsigned byte : 0 - 255
signed byte : -128 - 127
Однако оба имеют 256 возможных комбинаций значений, которые они могут представлять. Они отличаются только диапазоном значений, которые они могут представлять. Это диапазон типа данных.
Аналогично, это может быть расширено до типов int
, long
, float
, double
. Количество битов, назначаемых каждому типу данных, различно. Например:
int: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ <- 16 bits
long: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ <- 32 bits
Примечание. Фактическое число битов для каждого типа, например int
и long
, может зависеть от реализации и архитектуры, поэтому приведенная выше диаграмма не обязательно соответствует действительности.
На приведенной выше диаграмме тип int
представлен 16-разрядными значениями, которые представляют собой комбинации 2^16
или 65536
значений, которые он может представлять. Опять же, как и byte
, диапазон значений может быть положительным или разбитым на положительные и отрицательные:
unsigned int : 0 - 65535
signed int : -32768 - 32767
(Опять же, int
не обязательно должен быть 16-разрядным.)
Типы с плавающей точкой , такие как float
и double
, также представлены битами в памяти, но их представление данных отличается от целочисленных типов данных, таких как byte
и int
тем, что они будут хранить значение в памяти в виде двоичных дробей и экспонент. Типы с плавающей точкой также имеют концепцию диапазонов.
Подробную информацию о том, как значения с плавающей запятой определяются и рассчитываются в современных системах, см. В В Википедии есть статья о IEEE-754 .
Диапазоны данных типа данных возникают из комбинаций значений, которые могут быть представлены из объема памяти, выделенного для одной единицы одного типа данных, и из того, как эти возможные комбинации назначаются фактическим значениям, которые они представляют.