简体   繁体   English

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

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

What is the difference between signed and unsigned int?有符号整数和无符号整数有什么区别?

As you are probably aware, int s are stored internally in binary.您可能知道, int以二进制形式在内部存储。 Typically an int contains 32 bits, but in some environments might contain 16 or 64 bits (or even a different number, usually but not necessarily a power of two).通常int包含 32 位,但在某些环境中可能包含 16 或 64 位(甚至是不同的数字,通常但不一定是 2 的幂)。

But for this example, let's look at 4-bit integers.但是对于这个例子,让我们看看 4 位整数。 Tiny, but useful for illustration purposes.很小,但对于说明目的很有用。

Since there are four bits in such an integer, it can assume one of 16 values;由于这样的整数有 4 位,因此它可以采用 16 个值之一; 16 is two to the fourth power, or 2 times 2 times 2 times 2. What are those values? 16 是 2 的四次方,或 2 乘以 2 乘以 2。这些值是多少? The answer depends on whether this integer is a signed int or an unsigned int .答案取决于这个整数是有signed int还是unsigned int With an unsigned int , the value is never negative;对于unsigned int ,该值永远不会为负; there is no sign associated with the value.没有与该值相关联的符号。 Here are the 16 possible values of a four-bit 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

... and Here are the 16 possible values of a four-bit signed int : ...这里是四位有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

As you can see, for signed int s the most significant bit is 1 if and only if the number is negative.如您所见,对于有signed int s,当且仅当数字为负时,最高有效位为1 That is why, for signed int s, this bit is known as the "sign bit".这就是为什么,对于有signed int s,这个位被称为“符号位”。

In laymen's terms an unsigned int is an integer that can not be negative and thus has a higher range of positive values that it can assume.用外行的话来说,unsigned int 是一个不能为负的整数,因此它可以假设的正值范围更大。 A signed int is an integer that can be negative but has a lower positive range in exchange for more negative values it can assume.有符号 int 是一个整数,它可以是负数,但具有较低的正范围以换取它可以假设的更多负值。

int and unsigned int are two distinct integer types. intunsigned int是两种不同的整数类型。 ( int can also be referred to as signed int , or just signed ; unsigned int can also be referred to as unsigned .) int也可以称为signed int ,或者只是signedunsigned int也可以称为unsigned 。)

As the names imply, int is a signed integer type, and unsigned int is an unsigned integer type.顾名思义, int是有符号整数类型,而unsigned int无符号整数类型。 That means that int is able to represent negative values, and unsigned int can represent only non-negative values.这意味着int能够表示负值,而unsigned int只能表示非负值。

The C language imposes some requirements on the ranges of these types. C 语言对这些类型的范围提出了一些要求。 The range of int must be at least -32767 .. +32767 , and the range of unsigned int must be at least 0 .. 65535 . int的范围必须至少为-32767 .. +32767 ,而unsigned int的范围必须至少为0 .. 65535 This implies that both types must be at least 16 bits.这意味着两种类型都必须至少为 16 位。 They're 32 bits on many systems, or even 64 bits on some.它们在许多系统上是 32 位,在某些系统上甚至是 64 位。 int typically has an extra negative value due to the two's-complement representation used by most modern systems.由于大多数现代系统使用二进制补码表示, int通常具有额外的负值。

Perhaps the most important difference is the behavior of signed vs. unsigned arithmetic.也许最重要的区别是有符号和无符号算术的行为。 For signed int , overflow has undefined behavior.对于 signed int ,溢出具有未定义的行为。 For unsigned int , there is no overflow;对于unsigned int ,没有溢出; any operation that yields a value outside the range of the type wraps around, so for example UINT_MAX + 1U == 0U .任何产生超出类型范围的值的操作都会环绕,例如UINT_MAX + 1U == 0U

Any integer type, either signed or unsigned, models a subrange of the infinite set of mathematical integers.任何整数类型,无论是有符号还是无符号,都对无限数学整数集的子范围进行建模。 As long as you're working with values within the range of a type, everything works.只要您使用类型范围内的值,一切都会正常。 When you approach the lower or upper bound of a type, you encounter a discontinuity, and you can get unexpected results.当您接近类型的下限或上限时,您会遇到不连续性,并且可能会得到意想不到的结果。 For signed integer types, the problems occur only for very large negative and positive values, exceeding INT_MIN and INT_MAX .对于有符号整数类型,仅当非常大的负值和正值超过INT_MININT_MAX For unsigned integer types, problems occur for very large positive values and at zero .对于无符号整数类型,非常大的正值和零会出现问题。 This can be a source of bugs.这可能是错误的来源。 For example, this is an infinite loop:例如,这是一个无限循环:

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

because i is always greater than or equal to zero;因为i总是大于或等于零; that's the nature of unsigned types.这就是无符号类型的本质。 (Inside the loop, when i is zero, i-- sets its value to UINT_MAX .) (在循环内部,当i为零时, i--将其值设置为UINT_MAX 。)

Sometimes we know in advance that the value stored in a given integer variable will always be positive-when it is being used to only count things, for example.有时我们事先知道存储在给定整数变量中的值总是正的——例如,当它仅用于计数时。 In such a case we can declare the variable to be unsigned, as in, unsigned int num student;在这种情况下,我们可以将变量声明为无符号变量,例如unsigned int num student; . . With such a declaration, the range of permissible integer values (for a 32-bit compiler) will shift from the range -2147483648 to +2147483647 to range 0 to 4294967295. Thus, declaring an integer as unsigned almost doubles the size of the largest possible value that it can otherwise hold.使用这样的声明,允许的整数值范围(对于 32 位编译器)将从 -2147483648 到 +2147483647 的范围转移到 0 到 4294967295 的范围。因此,将整数声明为无符号几乎会使最大可能的大小增加一倍否则它可以持有的价值。

In practice, there are two differences:在实践中,有两个区别:

  1. printing (eg with cout in C++ or printf in C): unsigned integer bit representation is interpreted as a nonnegative integer by print functions.打印(例如 C++ 中的coutprintf中的printf ):无符号整数位表示被打印函数解释为非负整数。
  2. ordering : the ordering depends on signed or unsigned specifications. ordering :排序取决于签名或未签名的规范。

this code can identify the integer using ordering criterion:此代码可以使用排序标准识别整数:

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

char is considered signed in some compilers and unsigned in other compilers. char被认为是signed一些编译器和unsigned在其他的编译器。 The code above determines which one is considered in a compiler, using the ordering criterion.上面的代码使用排序标准确定在编译器中考虑哪一个。 If a is unsigned, after a-- , it will be greater than 0 , but if it is signed it will be less than zero.如果a是无符号的,在a--之后,它将大于0 ,但如果它是有signed ,它将小于零。 But in both cases, the bit representation of a is the same.但在这两种情况下,该位表示a是相同的。 That is, in both cases a-- does the same change to the bit representation.也就是说,在这两种情况下, a--对位表示进行相同的更改。

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

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