Signed versus Unsigned Integers

2019-01-02 19:17发布

Am I correct to say the difference between a signed and unsigned integer is:

  1. Unsigned can hold a larger positive value, and no negative value.
  2. Unsigned uses the leading bit as a part of the value, while the signed version uses the left-most-bit to identify if the number is positive or negative.
  3. signed integers can hold both positive and negative numbers.

Any other differences?

15条回答
几人难应
2楼-- · 2019-01-02 19:41

Signed integers in C represent numbers. If a and b are variables of signed integer types, the standard will never require that a compiler make the expression a+=b store into a anything other than the arithmetic sum of their respective values. To be sure, if the arithmetic sum would not fit into a, the processor might not be able to put it there, but the standard would not require the compiler to truncate or wrap the value, or do anything else for that matter if values that exceed the limits for their types. Note that while the standard does not require it, C implementations are allowed to trap arithmetic overflows with signed values.

Unsigned integers in C behave as abstract algebraic rings of integers which are congruent modulo some power of two, except in scenarios involving conversions to, or operations with, larger types. Converting an integer of any size to a 32-bit unsigned type will yield the member corresponding to things which are congruent to that integer mod 4,294,967,296. The reason subtracting 3 from 2 yields 4,294,967,295 is that adding something congruent to 3 to something congruent to 4,294,967,295 will yield something congruent to 2.

Abstract algebraic rings types are often handy things to have; unfortunately, C uses signedness as the deciding factor for whether a type should behave as a ring. Worse, unsigned values are treated as numbers rather than ring members when converted to larger types, and unsigned values smaller than int get converted to numbers when any arithmetic is performed upon them. If v is a uint32_t which equals 4,294,967,294, then v*=v; should make v=4. Unfortunately, if int is 64 bits, then there's no telling what v*=v; could do.

Given the standard as it is, I would suggest using unsigned types in situations where one wants the behavior associated with algebraic rings, and signed types when one wants to represent numbers. It's unfortunate that C drew the distinctions the way it did, but they are what they are.

查看更多
只若初见
3楼-- · 2019-01-02 19:41

You must used unsigned Integers when programming on Embedded Systems. In loops, when there is no need for signed integers, using unsigned integers will save safe necessary for designing such systems.

查看更多
回忆,回不去的记忆
4楼-- · 2019-01-02 19:43
  1. Yes, unsigned integer can store large value.
  2. No, there are different ways to show positive and negative values.
  3. Yes, signed integer can contain both positive and negative values.
查看更多
高级女魔头
5楼-- · 2019-01-02 19:43

The only guaranteed difference between a signed and an unsigned value in C is that the signed value can be negative, 0 or positive, while an unsigned can only be 0 or positive. The problem is that C doesn't define the format of types (so you don't know that your integers are in two's complement). Strictly speaking the first two points you mentioned are incorrect.

查看更多
孤独总比滥情好
6楼-- · 2019-01-02 19:46

Unsigned integers are far more likely to catch you in a particular trap than are signed integers. The trap comes from the fact that while 1 & 3 above are correct, both types of integers can be assigned a value outside the bounds of what it can "hold" and it will be silently converted.

unsigned int ui = -1;
signed int si = -1;

if (ui < 0) {
    printf("unsigned < 0\n");
}
if (si < 0) {
    printf("signed < 0\n");
}
if (ui == si) {
    printf("%d == %d\n", ui, si);
    printf("%ud == %ud\n", ui, si);
}

When you run this, you'll get the following output even though both values were assigned to -1 and were declared differently.

signed < 0
-1 == -1
4294967295d == 4294967295d
查看更多
笑指拈花
7楼-- · 2019-01-02 19:49

Over and above what others have said, in C, you cannot overflow an unsigned integer; the behaviour is defined to be modulus arithmetic. You can overflow a signed integer and, in theory (though not in practice on current mainstream systems), the overflow could trigger a fault (perhaps similar to a divide by zero fault).

查看更多
登录 后发表回答