问题
I'm learning C from CS50. When I run my code, it says 'signed integer overflow'.
#include <stdio.h>
#include <cs50.h>
int main(void)
{
int x = 41;
int c = 0;
while(x>=25)
{
c = c+1;
}
printf("%i\n", c);
}
Can someone explain what that means?
回答1:
Your while condition will always be true, meaning the loop will run forever, adding 1 to c
in each iteration.
Since c
is a (signed
) int
it means it will increment slowly to its max value, and after that the next increment would be UB (undefined behavior). What many machines will do in this specific UB is to turn c
negative, which I guess is not what you wanted. This happens due to a phenomenon called "signed integer overflow".
Let's assume 32-bit int
and using two's complement. A signed int
will look like this in binary sign bit (0 for positive, 1 for negative) | 31 bits
. zero will look like 000...00
, one like 000...01
and so on.
Max signed int will look like 0111...11
(2,147,483,647). When adding 1 to this number you'll get 100...000
which flipped the sign bit which will now result in a negative number. Adding another 1 to this will result in 100...001
which again has the sign bit on meaning it is still negative...
Declaring c
as unsigned would ensure c
remains non-negative. Also, making the loop end with while(x-- >= 25)
could also be a good idea :)
回答2:
Well... You have an infinite loop because your value x
will always be bigger than 25 since you dont decrease it.
since the loop is infinite, your value c
reaches the max size of an int (which is 2,147,483,647 if 4bytes).
You can try this in order to escape the infinite loop:
int main(void)
{
int x = 41;
int c = 0;
while (x >= 25)
{
c = c+1;
x--;
}
printf("%i\n", c);
}
回答3:
First of all, you need to know what a "signed integer overflow condition" is.
It is a condition which appears when a mathematical operation results in a number which is out of bounds of the data type, which is signed integer overflow in your case.
This happens because your loop goes on infinitely, because x >= 25
will always be true.
回答4:
"Signed integer overflow" means that you tried to store a value that's outside the range of values that the type can represent, and the result of that operation is undefined (in this particular case, your program halts with an error).
Since your while
loop never terminates (x >= 25
evaluates to true, and you never change the value of x
), you keep adding 1 to c
until you reach a value outside the range that a signed int
can represent.
Remember that in C, integral and floating-point types have fixed sizes, meaning they can only represent a fixed number of values. For example, suppose int
is 3 bits wide, meaning it can only store 8 distinct values. What those values are depends on how the bit patterns are interpreted. You could store "unsigned" (non-negative) values [0..7]
, or "signed" (negative and non-negative) values [-3...3]
or [-4..3]
depending on representation. Here are several different ways you can interpret the values of three bits:
Bits Unsigned Sign-Magnitude 1's Complement 2's Complement
---- -------- ------------- -------------- --------------
000 0 0 0 0
001 1 1 1 1
010 2 2 2 2
011 3 3 3 3
100 4 -0 -3 -4
101 5 -1 -2 -3
110 6 -2 -1 -2
111 7 -3 -0 -1
Most systems use 2's Complement for signed integer values. Yes, sign-magnitude and 1's complement have positive and negative representations for zero.
So, let's say c
is our 3-bit signed int
. We start it at 0
and add 1
each time through the loop. Eveything's fine until c
is 3
- using our 3-bit signed representation, we cannot represent the value 4
. The result of the operation is undefined behavior, meaning the compiler is not required to handle the issue in any particular way. Logically, you'd expect the value to "wrap around" to a negative value based on the representation in use, but even that's not necessarily true, depending on how the compiler optimizes arithmetic operations.
Note that unsigned integer overflow is well-defined - you'll "wrap around" back to 0.
来源:https://stackoverflow.com/questions/46789702/what-is-signed-integer-overflow