繁体   English   中英

有符号整数和无符号整数有什么区别

[英]What is the difference between signed and unsigned int

有符号整数和无符号整数有什么区别?

您可能知道, int以二进制形式在内部存储。 通常int包含 32 位,但在某些环境中可能包含 16 或 64 位(甚至是不同的数字,通常但不一定是 2 的幂)。

但是对于这个例子,让我们看看 4 位整数。 很小,但对于说明目的很有用。

由于这样的整数有 4 位,因此它可以采用 16 个值之一; 16 是 2 的四次方,或 2 乘以 2 乘以 2。这些值是多少? 答案取决于这个整数是有signed int还是unsigned int 对于unsigned int ,该值永远不会为负; 没有与该值相关联的符号。 以下是四位unsigned int的 16 个可能值:

bits  value
0000    0
0001    1
0010    2
0011    3
0100    4
0101    5
0110    6
0111    7
1000    8
1001    9
1010   10
1011   11
1100   12
1101   13
1110   14
1111   15

...这里是四位有signed int的 16 个可能值:

bits  value
0000    0
0001    1
0010    2
0011    3
0100    4
0101    5
0110    6
0111    7
1000   -8
1001   -7
1010   -6
1011   -5
1100   -4
1101   -3
1110   -2
1111   -1

如您所见,对于有signed int s,当且仅当数字为负时,最高有效位为1 这就是为什么,对于有signed int s,这个位被称为“符号位”。

用外行的话来说,unsigned int 是一个不能为负的整数,因此它可以假设的正值范围更大。 有符号 int 是一个整数,它可以是负数,但具有较低的正范围以换取它可以假设的更多负值。

intunsigned int是两种不同的整数类型。 int也可以称为signed int ,或者只是signedunsigned int也可以称为unsigned 。)

顾名思义, int是有符号整数类型,而unsigned int无符号整数类型。 这意味着int能够表示负值,而unsigned int只能表示非负值。

C 语言对这些类型的范围提出了一些要求。 int的范围必须至少为-32767 .. +32767 ,而unsigned int的范围必须至少为0 .. 65535 这意味着两种类型都必须至少为 16 位。 它们在许多系统上是 32 位,在某些系统上甚至是 64 位。 由于大多数现代系统使用二进制补码表示, int通常具有额外的负值。

也许最重要的区别是有符号和无符号算术的行为。 对于 signed int ,溢出具有未定义的行为。 对于unsigned int ,没有溢出; 任何产生超出类型范围的值的操作都会环绕,例如UINT_MAX + 1U == 0U

任何整数类型,无论是有符号还是无符号,都对无限数学整数集的子范围进行建模。 只要您使用类型范围内的值,一切都会正常。 当您接近类型的下限或上限时,您会遇到不连续性,并且可能会得到意想不到的结果。 对于有符号整数类型,仅当非常大的负值和正值超过INT_MININT_MAX 对于无符号整数类型,非常大的正值和零会出现问题。 这可能是错误的来源。 例如,这是一个无限循环:

for (unsigned int i = 10; i >= 0; i --) [
    printf("%u\n", i);
}

因为i总是大于或等于零; 这就是无符号类型的本质。 (在循环内部,当i为零时, i--将其值设置为UINT_MAX 。)

有时我们事先知道存储在给定整数变量中的值总是正的——例如,当它仅用于计数时。 在这种情况下,我们可以将变量声明为无符号变量,例如unsigned int num student; . 使用这样的声明,允许的整数值范围(对于 32 位编译器)将从 -2147483648 到 +2147483647 的范围转移到 0 到 4294967295 的范围。因此,将整数声明为无符号几乎会使最大可能的大小增加一倍否则它可以持有的价值。

在实践中,有两个区别:

  1. 打印(例如 C++ 中的coutprintf中的printf ):无符号整数位表示被打印函数解释为非负整数。
  2. ordering :排序取决于签名或未签名的规范。

此代码可以使用排序标准识别整数:

char a = 0;
a--;
if (0 < a)
    printf("unsigned");
else
    printf("signed");

char被认为是signed一些编译器和unsigned在其他的编译器。 上面的代码使用排序标准确定在编译器中考虑哪一个。 如果a是无符号的,在a--之后,它将大于0 ,但如果它是有signed ,它将小于零。 但在这两种情况下,该位表示a是相同的。 也就是说,在这两种情况下, a--对位表示进行相同的更改。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM