D. De
D. De

Reputation: 19

Bitwise operations: C vs. Python

I'm faced with a weird problem here. Consider this piece of code:

#include <stdio.h>
    int main()
    {
        printf("%u\n", (55 & 00000111) + 1);
        return 0;
    }

This code, upon being compiled and executed, yields 2 as the result.

Python, on the other hand, yields this:

>>> (55 & 0b00000111) + 1
8

Why the different results?

Upvotes: 1

Views: 2131

Answers (4)

Deepak Gupta
Deepak Gupta

Reputation: 1

The code you are using for C uses octal integers which when converted to hex looks like

0xfollowed by eight characters(32 bits) here in octal ... 001 001 001

1 hex character is 4 bits. whereas code in python uses binary literals.

Upvotes: 0

Numbers prefixed with 0 in C are not in base-2 (binary), but base-8 (octal) In Python, the same can be achieved by prefixing the number with 0o

Python 3.5.3 (default, Jan 19 2017, 14:11:04) 
>>> (55 & 0o00000111) + 1
2
>>> 0o00000111
73
>>> 1 * 8 ** 2 + 1 * 8 ** 1 + 1 * 8 ** 0
73

C does not support binary integer constants. However, as an extension, GCC does, so

#include <stdio.h>
int main()
{
    printf("%u\n", (55 & 0b00000111) + 1);
    return 0;
}

Can be compiled with GCC:

% gcc bin.c && ./a.out
8

As others have pointed out, hex is much more convenient than binary anyway - you just need to remember how each of the hex digit 0-F looks in binary, and replace groups of 4 bits with a single hex digit:

0000 | 0111
   0      7
--->   0x07

And unlike binary notation, this works in all C compilers and Python versions alike.

Upvotes: 0

CIsForCookies
CIsForCookies

Reputation: 12827

Numbers that start with prefix 0 have octal representation, meaning 00000111 is octal 111 == 1 + 8 + 64 == 73.

0b00000111 is in binary representation, meaning it has the value of 1 + 2 + 4 == 7.

When using printf("%u\n", (55 & 00000111) + 1); the result is 2 since the only bit on in both numbers is the LSB --> it equals 1, and added with 1, you get 2.

When using (55 & 0b00000111) + 1, 55 == 32 + 16 + 4 + 2 + 1 meaning all 3 last bits are on, and that equals 7, and added with 1, you get 8.

Upvotes: 2

taskinoor
taskinoor

Reputation: 46037

C doesn't have a literal for binary. So 00000111 is not binary literal as you assumed. Instead it is interpreted as octal 111 (or decimal 73) as 0 prefix denotes octal in C. In case of Python 0b00000111 is a proper binary literal (note the b after 0 prefix). That's why you are getting different results in C and Python.

In case you want to use binary literal in C code, in my opinion the best way is to use hexadecimal literal starting with 0x since one hex digit is equivalent to 4 binary digits and it's very easy to convert hex literal to binary literal and vice versa. For example, you could have used 0x7 in your example.

printf("%u\n", (55 & 0x7) + 1);

Upvotes: 5

Related Questions