-11

I have written and compiled the following code:

void main()
{ 
    printf("%d", -10 & 5);
}
  • 1
    Do you know what the `&` operator is? – Jabberwocky May 27 '19 at 10:08
  • 1
    @Sonic-BO_oM what should the output be according to you? – Sandy May 27 '19 at 10:08
  • 3
    Run the program to see what it is. Then read about https://en.wikipedia.org/wiki/Bitwise_operations_in_C#Bitwise_AND_& – klutt May 27 '19 at 10:08
  • 3
    @Broman: Running the program does not answer the question why the output is 4, nor does it assure that the output will be 4 in every C implementation. (In general, running a program would not even ensure that the output obtained is the output that would be obtained in every execution of the program in the same C implementation.) Additionally, information on the bitwise AND operator is insufficient to answer the question, as the result also depends on how numbers are represented using bits. – Eric Postpischil May 27 '19 at 10:10
  • Steps of the analysis: lookup the `&` operator. Aha... Now lookup the bit pattern of the number `-10` and the number `5`. Now figure out what the result is when the `&` operator is applied. That's what will be printed. – Paul Ogilvie May 27 '19 at 10:14
  • @PaulOgilvie: Where does one lookup the bit pattern of the number −10? – Eric Postpischil May 27 '19 at 10:14
  • @EricPostpischil, from the paper where you are writing it down or from the debugger. – Paul Ogilvie May 27 '19 at 10:15
  • @EricPostpischil True, it's not enough to properly answer the question, but those two things should still have been done before posting the question. I kind of explained why I downvoted this for lack of research. – klutt May 27 '19 at 10:15
  • And negative numbers have a different bit pattern. They are in the 2's complement form. See https://en.wikipedia.org/wiki/Two%27s_complement – J...S May 27 '19 at 10:16
  • @PaulOgilvie: I wrote “−10” on a piece of paper. No bit pattern appeared. Whatever you meant by that is incomprehensible. In a debugger, lldb, “print -10” shows “-10”, not a bit pattern. – Eric Postpischil May 27 '19 at 10:17
  • @Sonic-BO_oM Here is a nice article on the subject: https://wiki.sei.cmu.edu/confluence/display/c/INT13-C.+Use+bitwise+operators+only+on+unsigned+operands – klutt May 27 '19 at 10:17
  • 1
    @J...S: Negative numbers are not always represented that way. You and others are merely spouting knowledge **you have already learned** without considering the steps somebody who **does not know this knowledge** has to go through to acquire it. You are treating as “obvious” what is actually not obvious at all. Once you actually put together all the information that actually has to be explained to explain the question, then you have an answer, which should be posted as an answer, not a comment. – Eric Postpischil May 27 '19 at 10:18
  • 1
    Oh @EricPostpischil, I gave you a higher esteem. Maybe look at the other side of the paper? – Paul Ogilvie May 27 '19 at 10:18
  • @EricPostpischil What other ways are negative numbers represented? And are those methods still being used? I'm just asking because I don't know. – J...S May 27 '19 at 10:21
  • 1
    @J...S Here you can read about different methods https://en.wikipedia.org/wiki/Signed_number_representations – klutt May 27 '19 at 10:23
  • 1
    @J...S: I have explained them in my answer. Both two’s complement and sign-and-magnitude are still in common use, but sign-and-magnitude is mostly just used for floating-point. Actually, floating-point commonly uses two methods at the same time: sign and magnitude for the whole number and offset binary for the exponent. – Eric Postpischil May 27 '19 at 10:39
  • Also change the return type of `main()`. It should return an `int`. See https://stackoverflow.com/questions/636829/difference-between-void-main-and-int-main – J...S May 28 '19 at 06:29

1 Answers1

6

In C, in the result of the binary &, each bit depends on the two corresponding bits in the operands. If the bit in the same position is set (1) in both operands, it is set in the result. If it is clear (0) in either operand, it is clear in the result. For example, given bits 0011 and 0101, the & operator would produce 0001, because only in the last position is the bit set in both operands.

You likely already know that positive integers are represented with binary. The bit positions are numbered starting from 0 on the “right”, then 1 for the next position, 2, 3, and so on. The bit in position i represents a value of 2i, so bit 0 represents 1, bit 1 represents 2, bit 2 represents 4, bit 3 represents 8, bit 4 represents 16, and so on. The value represented by all the bits is the sum of the values of the bits that are set to 1. So 101 represents 5, because the bits for 22 = 4 and 20 = 1 are set, and 4+1 = 5.

The C standard specifies three rules that a C implementation may use to represent negative numbers (in C 2018 6.2.6.2 2):

  • One of the bits represents a sign. If the sign bit is 0, the value is the same as above. If the sign bit is 1, the value is negated. So, if the first bit is the sign bit, then 5 is 0101 is 5, and −5 is 1101. This is called sign and magnitude.
  • One of the bits represents a sign, and, if a number is negative, all of the bits are inverted. So 5 is 0101, and −5 is 1010. This is called one’s complement.
  • One of the bits represents a sign, and, if the number is negative (let’s call it x), the bits are set in the pattern that would be used for 2Nx, where N is the number of bits. For example, for four bits, 2N = 16, and 5 is 0101, and −5 is represented with the bits for 16−5 = 11, which are 1011. This is called two’s complement.

In early computer hardware and software, all of the above were tried. The last, two’s complement, is overwhelming dominant in modern computing for integers. (Most floating-point uses sign and magnitude.) Nonetheless, the C standard still permits implementations to use any of the methods.

Because of this, the result of -10 & 5 is implementation-dependent. I will illustrate using eight bits, with a space to group them into two sets of four bits for visibility:

With two’s complement:

  • −10 is represented with 1111 0110 (256 − 10 = 246 = 128+64+32+16+4+2), 5 uses 0000 0101, and −10 & 5 is 0000 0100, which represents 4.

With one’s complement:

  • −10 is represented with 1111 0101, 5 uses 0000 0101, and −10 & 5 is 0000 0101, which represents 5.

With sign and magnitude:

  • −10 is represented with 1000 1010, 5 uses 0000 0101, and -10 & 5 is 0000 0000, which represents 0.

Thus, a C implementation that conforms to the C standard could produce 0, 4, or 5 for -10 & 5, but 4 is by far the most common result.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312