В C, в контекстах, не связанных с целочисленным продвижением , были определены значения без знака, которые ведут себя как члены «обертывающего» абстрактного алгебраического кольца (поэтому для любых X и Y XY даст уникальное значение, которое при добавлении к Y даст X ), в то время как целочисленные типы со знаком были определены как ведущие себя как целые числа, когда вычисления находились в определенном диапазоне, и позволяли делать что-либо вообще, когда вычисления выходили за рамки этого. Числовая семантика в C #, однако, совершенно другая. Когда внутри проверенного числового контекста оба типа со знаком и без знака ведут себя как целые числа, при условии, что вычисления остаются в диапазоне и выдают, OverflowException
когда они не делают; в неконтролируемом контексте они оба ведут себя как алгебраические кольца.
Единственный раз, как правило, стоит использовать любой тип данных меньшего размера, чем Int32
когда это необходимо для упаковки или распаковки вещей для компактного хранения или транспортировки. Если нужно хранить полмиллиарда положительных чисел, и все они будут в диапазоне от 0 до 100, использование одного байта вместо четырех сэкономит 1,5 гигабайта памяти. Это большая экономия. Однако, если фрагмент кода должен хранить в общей сложности пару сотен значений, создание каждого из них одним байтом, а не четырьмя, сэкономит около 600 байтов. Наверное, не стоит беспокоиться.
Что касается неподписанных типов, единственное время, когда они действительно полезны, - это при обмене информацией или при делении чисел на части. Если, например, нужно выполнить математику для 96-разрядных целых чисел, то, вероятно, будет гораздо проще выполнять вычисления для групп из трех беззнаковых 32-разрядных чисел, чем для групп целых чисел со знаком. В противном случае не так много ситуаций, когда диапазон 32- или 64-разрядного значения со знаком был бы неадекватным, но такого же размера беззнакового значения было бы достаточно.