tags:

views:

241

answers:

8

Please explain the following paragraph.

"The next question is whether we can assign a certain value to a variable without losing precision. It is not sufficient if we just check for overflow during the addition or subtraction, because someone might add 1 to -5 and assign the result to an unsigned int. Then the actual addition does not overflow, but the result still does not fit."

when i am adding 1 to -5 i dont see any reason to worry.the answer is as it should be -4. so what is the problem of result not being fit?? you can find the full article here through which i was going:

http://www.fefe.de/intof.html

+5  A: 

Try assigning it to a unsigned int, not an int.

The term unsigned int is the key - by default an int datatype will hold negative and positive numbers; however, unsigned ints are always positive. They provide this option because uints can technically hold greater positive values than regular signed ints because they do not need to use a bit to keep track of whether or not its negative or positive.

Please see:

http://stackoverflow.com/questions/247873/signed-versus-unsigned-integers

cakeforcerberus
A: 

By definition the number -4 cannot be represented in an unsigned int. -4 is a signed integer. The same goes for any negative number.

When you assign a negative integer to an unsigned int the actual bits of the number do not change, but they are merely represented differently. You'll get some ridiculously-large number due to the way integers are represented in binary (two's complement).

In two's complement, -4 is represented as 0xfffffffc. When 0xfffffffc is represented as an unsigned int you'll get the number 4,294,967,292.

Andrew Keeton
The bits change as adequate to fulfill the requirement that `-1 == UINT_MAX`, `-2 == UINT_MAX - 1`, etc.. (modulo arithmetic). Only for two's complement, bits do not change. The number for two's complement is high because it's the required result, not *because* of two's complement.
Johannes Schaub - litb
i think there will not be represented differently as u hv mentioned but interpreted differently.-4 will be in two's complement form ,so when it is interpreted as unsigned it is actually be interpreted as a very large number.
mawia
@litb I guess I'm taking liberties by assuming a certain representation. Officially, two's complement is not the only representation for integers when it comes to the C standard, but it's probably the most likely.
Andrew Keeton
I did not say you are wrong nor did i eventually downvote you or something, but i clarified what you said in your answer, because it sounds like that the bits don't change in all cases. If you were on a one's complement machine and did `unsigned int a = -1;` then the bits change from `111...110` to `111...111`, for example. On a sign-magnitude, they go from `100....001` to `111...111`.
Johannes Schaub - litb
+2  A: 

The problem is that you're storing -4 in an unsigned int. Unsigned ints can only contain zero and positive values. If you assign -4 to one, you'll actually end up getting a very large positive number (the actual value depends on how wide an int you're using).

T.J. Crowder
A: 

Unsigned variables, like unsigned int, cannot hold negative values. So assigning 1 - 5 to an unsigned int won't give you -4. I'm not sure what it'll give you, it's probably compiler specific.

J. Pablo Fernández
+2  A: 

The problem is that the sizes of storage such as unsigned int can only hold so much. With 1 and -5 it does not matter, but with 1 and -500000000 you might end up with a confusing result. Also, unsigned storage will interpret anything stored in it as positive, so you cannot put a negative value in an unsigned variable.

Two big things to watch out for:
1. Overflow in the operation itself: 1 + -500000000
2. Issues in casting: (unsigned int)(1 + -500)

Justin
A: 

Some code:

signed int first, second;
unsigned int result;

first = obtain(); // happens to be 1
second = obtain(); // happens to be -5
result = first + second; // unexpected result here - very large number - and it's too late to check that there's a problem

Say you obtained those values from keyboard. You need to check before addition that the result can be represented in unsigned int. That's what the article talks about.

sharptooth
1.#define assign(dest,src) ({ \2. typeof(src) __x=(src); \3. typeof(dest) __y=__x; \4. (__x==__y \})can you plz explain the above macro ,i am struck at the 4th line.if am getting that if the condition is true then __y is assigned to dest ,but what if the condition dont come out to be true then situation is not clear??can you plz explain it.it is there in the link.
mawia
It's easy to check - run { unsigned int dest; signed int src = 5; assign( dest, src ); } and you see that dest remains unchanged if the check fails.
sharptooth
+3  A: 

The binary representation of -4, in a 32-bit word, is as follows (hex notation)

0xfffffffc

When interpreted as an unsigned integer, this bit pattern represents the number 2**32-4, or 18446744073709551612. I'm not sure I would call this phenomenon "overflow", but it is a common mistake to assign a small negative integer to a variable of unsigned type and wind up with a really big positive integer.

This trick is actually exploited for bounds checking: if you have a signed integer i and want to know if it is in the range 0 <= i < n, you can test

if ((unsigned)i < n) { ... }

which gives you the answer using one comparison instead of two. The cast to unsigned has no run-time cost; it just tells the compiler to generate an unsigned comparison instead of a signed comparison.

Norman Ramsey
A: 

You have to remember that fundamentally you're working with bits. So you can assign a value of -4 to an unsigned integer and this will place a series of bits into that memory location. Those bits can be interpreted as -4 in certain circumstances. One such circumstance is the obvious one: you've told the compiler/system that the bits in that memory location should be interpreted as a two's compliment signed number. So if you do printf("%s",i) prtinf does its magic and converts the two's compliment number to a magnitude and sign. The magnitude will be 4 and the sign will be negative, so it displays '-4'.

However, if you tell the compiler that the data at that memory location is not signed then the bits don't change but instead their interpretation does. So when you do your addition, store the result in an unsigned integer memory location and then call printf on the result it doesn't bother looking for the sign because by definition it is always positive. It calculates the magnitude and prints it. The magnitude will be off because the sign information is still encoded in the bits but it's treated as magnitude information.

Stephen Friederichs