views:

465

answers:

6

In the following code segment what will be:

  • the result of function
  • value of x
  • value of y
    {
         unsigned int x=-1;
         int y;
         y = ~0;
         if(x == y)
             printf("same");
         else
             printf("not same");
     }
a. same, MAXINT, -1
b. not same, MAXINT, -MAXINT
c. same , MAXUINT, -1
d. same, MAXUINT, MAXUINT
e. not same, MAXINT, MAXUINT

The answer is A but can someone explain me how its works or can just explain the snippet??

I know it's about two's complement n etc.. I should modify the Qs..what is the significance of MAXINT and -1 ? It is because of unsigned int and int thing - am I right ?

+8  A: 

Its pretty easy. The twos complement representation of -1 is 0xFFFFFFFF. Hence that is what x contains.

The complement operator (~) flips all the bits. So the complement of 0 is a 32-bit number with all the bits set to 1 or 0xFFFFFFFF.

Edit: As pointed out int he comments. The answer is not A. If it was then it would be saying 0x7FFFFFFF and 0xFFFFFFFF are the same. They're not. The real answer is C (Assuming MAXUNIT is a typo ;)).

Goz
yeah i know its about twos compliment may be my question ws wrong ,,why in ans options they hav given MAXINT n -1 etc things ,,i dont understand the significance its obvious that they are same...bt they have three options saying same n what about other things with the options...plz tel me that
shraddha
Doesn't that mean the correct answer should be c (assuming UNIT is supposed to be UINT)? That's what I would have said anyway.
sepp2k
okay is it coz -1 is unsigned so it gives MAXINT n as y is int it gives us -1??
shraddha
I figured the compiler would complain about assigning -1 to an unsigned int, but it does compile - interesting.
Darel
@Darel in fact... C is C! You can map to asm more easier than any other language (asm apart!)... an assembler can't complain for, say "mov eax, -1" or "mov eax, FFFFFFFFh"... cpu can't distinguish... :D
ShinTakezou
if MAXUNIT is MAXUINT, I agree with @sepp2k !! it should be: same MAXUINT, -1
ShinTakezou
+2  A: 

It's because of twos-complement

The flipping of the bits results in a bit pattern that matches -1

John Weldon
yeah i know its about twos compliment may be my question ws wrong ,,why in ans options they hav given MAXINT n -1 etc things ,,i dont understand the significance its obvious that they are same...bt they have three options saying same n what about other things with the options....plz tel me that ..
shraddha
I was not aware of the existance of MAXUNIT... as for MAXINT, the A) says MAXINT is as -1 (int), and you already know why, knowing the 2s technics. The two values (MAXINT, -1; MAXUNIT, -MAXUNIT) are the values being compared "effectively", I think. So, looking backward, even ignoring what MAXUNIT is, the answers must be the first, since MAXINT and -1 are the same and what you get from your program... (a bit tautological?)
ShinTakezou
my previous comment is wrong: MAXUINT is equal to -1. (being MAXUNIT indeed MAXUINT)
ShinTakezou
+1  A: 

Since in the first unsigned int, you put -1, but from the unsigned int point of view it is 0xFFFFFFFF (this is how negative integers are stored into a computer); in the second case the bitwise not does not look at the "kind" at all and "transform" 0 into 1 and viceversa, so all zeros of 0 becomes 1 (looking at bits), so you obtain 0xFFFFFFFF.

The next question is, why comparing an unsigned integer with a signed integer does not distinguish them? (numerically 4294967295 is not equal to -1 of course, even though their representation in a computer is the same). Indeed it could, but clearly C does not mandate such a distinction, and it is "natural", since processor aren't able to do it of their own (I am not sure about this last sentence being always true, ... but it is for most processor): to take into account this distinction in asm, you have to add extra code.

From the C point of view, you have to decide if to cast int into unsigned int, or signed int into unsigned int. But a negative number can't be cast into a unsigned one, of course, and on the other hand, an unsigned number could cause overflow (e.g. for 4294967295 you need a 64bit register (or a 33bit regster!) to be able to have it and still be able to calculate its negative value)...

So likely the most natural thing is to avoid strange casting, and permit a "cpu like" comparison, which in this case lead to 0xFFFFFFFF (-1 on 32 bit) compared to 0xFFFFFFFF (~0 on 32bit), which are the same, and more in genereal one can be considered as MAXUINT (the maximum unsigned integer that can be hold) and the other as -1. (Take a look at your machine limits.h include to check it)

ShinTakezou
Important comment: as said elsewhere, I agree with sepp2k, if MAXUNIT is indeed MAXUINT, since MAXUINT is 4294967295 (on a 32 bit machine) and MAXINT is indeed 2147483647, on 32 bit machine... , so C is the right one, not A
ShinTakezou
meta-comment on the comment: I made this comment and others before sepp2k posted his answer: I refer to his/her comments.
ShinTakezou
A: 

this question is not that hard,the answers above should be good enough for you to understand,if not,grab a book about c's data types and their corresponding interal mathematical representations and other related stuff.

Tracy
+8  A: 

If you run this program, you will see that the answer a is wrong and c is the correct answer:

#include <stdio.h>
#include <limits.h>

int main() {
    unsigned int x=-1;
    int y;
    y = ~0;
    if(x == y)
        printf("same\n");
        if(x==INT_MAX) printf("INT_MAX\n");
        if(x==UINT_MAX) printf("UINT_MAX\n");
    else
        printf("not same");
    return 0;
}
sepp2k
okay thats means ans is C...final..Thanks a lot
shraddha
@shraddha: Unfortunately the C language leaves a lot unspecified so running the program on one particular implementation (even one known to be 100% conforming) doesn't tell you what the language specifies. This is only one 'final' answer.
Charles Bailey
+6  A: 

unsigned int x=-1;

1 is an integer literal and has type int (because it fits in an int). Unary - applied to an int causes no further promotion so -1 is an int with value -1.

When converted to an unsigned int modulo 2^N arithmetic is used where N is the number of value bits in an unsigned int. x has the value 2^N - 1 which is UINT_MAX (What's MAX_UNIT?).

int y;
y = ~0;

Again 0 is type int, in C all the allowed representations of int must have all the value bits of an int representing 0 as 0. Again no promotion happens for unary ~ so ~0 is an int with all value bits being 1. What it's value is is implementation dependent but it is negative (the sign bit will be set) so definitely neither of UINT_MAX or INT_MAX. This value is stored in y unchanged.

if(x == y)
    printf("same");
else
    printf("not same");

In this comparison y will be converted to unsigned int in order to be compared with x which is already an unsigned int. As y has an implementation value, the value after conversion to unsigned int is still implementation defined (although the conversion itself is modulo 2^N and fully specified). The result of the comparison is still implementation defined.

So in conclusion:

implementation defined, UINT_MAX, implementation defined

In practice on ones' complement:

not same, UINT_MAX, -0 (aka 0)

sign plus magnitude:

not same, UINT_MAX, INT_MIN

two's complement:

same, UINT_MAX, -1

Charles Bailey
Do I understand correctly, that it actually depends on the implementation and the question as presented is somewhat flawed? I think the relevant part of the standard is [section 6.2.6.2 §2](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf)(pdf)
Lucas
@Lucas: Yes and yes.
Charles Bailey
+1 I did not realize that the signed integer implementation is *not* defined in the C standard. It can be *two's complement*, *one's complement* or *sign and magnitude*. This is something that needs to be taken in consideration (even though it is practically always two's complement).
PauliL