Например в C#
byte: хранит целое число от 0 до 255 и занимает 1 байт.
ushort: хранит целое число от 0 до 65535 и занимает 2 байта.
uint: хранит целое число от 0 до 4294967295 и занимает 4 байта.
---
Если нам понадобится число 65536, то ushort не хватит 1 бита. И мы будем использовать uint.
"Эффективно" мы будем использовать только 1 байт. Его бит, которого нам так не хватало. Второй байт нам не нужен.
Логично, чтобы был тип данных 3 байта. Но такого типа данных нет. Но есть 4, 8, 16.
И для числа в "8 байт+1бит" мы вынуждены использовать 16 байт. Хотя могли бы 9.
И мы так и делаем, и это считается нормой. Других вариантов нет.
В тоже время, когда для "числа" 255 задают тип ushort, это считается неверным. Лишняя трата ресурсов/памяти. Да и не логично и путает программиста.
Причин для этого множество и не последнюю роль в этом играют требования (или рекомендации) выравнивания данных в памяти. Из соображений производительности на многих (или даже на большинстве) современных платформах данные должны хранится в памяти на границе, кратной степени двойки. Поэтому даже если вы изобретете тип, состоящий их 3 байтов, все равно по соображениям выравнивания вам придется хранить данные этого типа на 4-байтовой адресной границе, тем самым фактически теряя каждый четвертый байт впустую. В такой ситуации нет смысла заводить 3-байтовый тип, если его можно сразу фактически "бесплатно" сделать 4-байтовым.
В ситуациях (или на платформах), где соображения тщательной экономии памяти являются более важными, чем соображения производительности, ваши аргументы будут более вескими. И для таких ситуаций многие языки программирования предоставляют средства для реализации именно таких более компактных типов.
Потому что ненапасешься типов данных под каждую ситуацию. Надо вам 3 байта - делайте массив трех байт.
Плюс все это проецируется таки в регистры процессора, кеш и прочее. И int в регистр пройдет со свистом, в отличие от вашего 5-байтного типа данных. Вот и оптимизируют железо (читай даже - разрабатывают) под фиксированные размерности.
Можно добавлю? Евгений Иванов, оптимизирующие компиляторы ещё и данные и команды процессора выравнивают по размеру слова. Если, например, команда оказывается короче чем длина слова, то специально добавляются дырки, чтобы следующая команда была выровнена именно по границе слова. На x86, вроде, команда NOP была.
GavriKos, в C# мы видим
ushort: хранит целое число от 0 до 65535 и занимает 2 байта.
short: хранит целое число от -32768 до 32767 и занимает 2 байта.
---
Это ли не та самая ситуация? Положительные числа есть, но возникла "ситуация".
И вводят новый тип данных, того же размера. Нужно же как то хранить отрицательные числа.
Вообщем, как я понял - на это просто забили, клепают железки и память побольше (кому нужно считать байты, когда оперативка, например, 16-32 ГБ).
потому что восемь. :) На что бы вы не умножили восемь [имеется ввиду любое натуральное] - получите чётное число. 8, 16, 24, 32, 40, 48, 56, 64 и т.д.
Кампутер с "данными" меньше байта не работает.
Если вам нужны определённые наборы байт - как написано выше - используйте массивы. Или же структуры. Например в с# есть очень удобные и быстроработающие штуки для этого.
Единственный момент с c# - это то что не юзайте структуры длиннее четырёх интов - уже будут тормозить. Наборы байт длиннее четырёх интов лучше представлять массивами.