Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

programming languages - Why Do We have unsigned and signed int type in C?

I am a beginner in C . I have recently learned about 2's Complement and other ways to represent negative number and why 2's complement was the most appropriate one.

What i want to ask is for example,

int a = -3;
unsigned int b = -3; //This is the interesting Part.

Now , for the conversion of int type

The standard says:

6.3.1.3 Signed and unsigned integers

When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged.

Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.

The first paragraph can't be used as -3 can't be represented by unsigned int.

Therefore paragraph 2 comes to play and we need to know the maximum value for unsigned int. It can be found as UINT_MAX in limits.h. The maximum value in this case is 4294967295 so the calculation is:

-3 + UINT_MAX + 1 = -3 + 4294967295 + 1 = 4294967293  

Now 4294967293 in binary is 11111111 11111111 11111111 11111101 and -3 in 2's Complement form is 11111111 11111111 11111111 11111101 so they are essentially same bit representation , it would be always same no matter what negative integer i am trying to assign to unsigned int.So isn't unsigned type redundant.

Now i know that printf("%d" , b) is an undefined behavior according to standard, but isn't that what is a reasonable and more intuitive way to do things. As representation will be same if negative are represented as 2's Complement and that is what we have now , and other ways used are rare and most probably will not be in future developments.

So if we could have only one type say int , now if int x = -1 then %d checks for the sign bit and print negative number if sign bit is 1 and %ualways interpret the plain binary digit (bits) as it is . Addition and subtraction are already dealt with because of using 2's complement. So isn't this more intuitive and less complex way to do things.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

It's handy to have both for input, output and computation. For example, comparison and division come in signed and unsigned varieties (btw, at the bit level multiplication is the same for unsigned and 2's complement signed types, just like addition and subtraction and both may compile into the same multiplication instruction of the CPU). Further, unsigned operations do not cause undefined behavior in case of overflow (except for division by zero), while signed operations do. Overall, unsigned arithmetic is well defined and unsigned types have a single representation (unlike three different ones for signed types, although, these days in practice there's just one).

There's an interesting twist. Modern C/C++ compilers exploit the fact that signed overflows result in undefined behavior. The logic is that it never happens and therefore some additional optimizations can be done. If it actually happens, the standard says it's undefined behavior, and your buggy program is legally screwed. What this means is that you should avoid signed overflows and all other forms of UB. However, sometimes you can carefully write code that never results in UB, but is a bit more efficient with signed arithmetic than with unsigned.

Please study the undefined, the unspecified and the implementation-defined behaviors. They are all listed at the end of the standard in one of the annexes (J?).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...