无符号数

无符号数unsigned)是计算机编程中的一种数值资料型别有符号数signed)可以表示特定类型规定范围内的整数(包括负数),而无符号数只能表示非负数(0及正数)。

有符号数能够表示负数的代价是能够表示的正数范围的缩小,因为其约一半的数值范围要用来表示负数(如8位有符号整数中,对应8位无符号整数表示128~255的部分被用于表示-127~-1)。无符号数可以利用其所占有的所有来表示较大的数。

例如,16位有符号整数可表示 -32768~32767 之间的任意整数,而16位无符号整数可表示 0~65535 之间的数。若将有符号数转换为二进制,则其数值类型允许的最左一位用于表示符号(1为负数,0为正数和0),但在无符号数中,最左一位与其右各位一样用于表示数值。

大多数架构机器语言不区分有符号数及无符号数。然而算术指令通常设定进位标志等CPU标志,为无符号算术及溢出标志设定。这些标志能够被带入随后的分支及算术指令中。

C语言及大部分C的派生语言为其所有有符号数类型及char类型提供了对应的无符号类型[1]。在这些语言中,若存在显式的unsigned标识符,则将此数标识为无符号,否则为有符号(char类型除外),对应地存在signed标识符用于标识有符号数。为数值添加U后缀也可将此数值标识为无符号数。例如,在32位数中,0xFFFFFFFF表示-1,但0xFFFFFFFFU表示4294967295。

编译器在遇到有符号数与无符号数间的比较、算术等操作时常会发出警告,因为可能因其范围不同而导致溢出。C/C++语言规定无符号整数运算不存在溢出,如果结果超出了无符号类型能表示的最大数,则做模运算取余数。[2]例如,对于uint32的 2-3, 其结果对0x10000模运算取余数,最终结果为0xFFFF。

参考文献

  1. ^ ISO/IEC 9899:2011. International Organization for Standardization. [2020-03-08]. (原始内容存档于2020-03-28) (英语). §6.2.5/6: For each of the signed integer types, there is a corresponding (but different) unsigned integer type (designated with the keyword unsigned) that uses the same amount of storage (including sign information) and has the same alignment requirements. 
  2. ^ ISO/IEC 9899:2011. International Organization for Standardization. [2020-03-08]. (原始内容存档于2020-03-28) (英语). §6.2.5/9: A computation involving unsigned operands can never overflow,because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type.