We help IT Professionals succeed at work.

The bitwise OR in C

John Kruijt
John Kruijt asked
on
Hi there, I'm new in C and using a downloaded tutorial to practice and learn. Heading up to the 17th chapter I have a question I can't find an answer to.
The exercise is showing me the use of the bitwise OR:
#include <stdio.h>
#define SET 32

char *binbin(int n);

int main()
{
    int bor, result;

    printf("Type a value from 0 to 255: ");
    scanf("%d",&bor);
    result = bor | SET;
 
    printf("\t%s\t%d\n",binbin(bor),bor);
    printf("|\t%s\t%d\n",binbin(SET),SET);
    printf("=\t%s\t%d\n",binbin(result),result);
    return 0;
}

char *binbin(int n)
{
    static char bin[9];
    int x;

    for (x=0;x<8;x++)
    {
        bin[x] = n & 0X80 ? '1' : '0';
        n << 1;
    }
    bin[x]='\0';
    return(bin);
}

Open in new window

When I run this and I enter a value of less or equal to 95, I get this result:
Type a value from 0 to 255: 95
        01011111        95
|       00100000        32
=       01111111        127

Open in new window

When I enter a value greater then 95, the outcome is:
Type a value from 0 to 255: 96
        01100000        96
|       00100000        32
=       01100000        96

Open in new window

In first I thought the binbin function is giving the wrong output. To test that I added the next line directly after the bitwise OR
printf("This is the result from bitwise OR: %d\n",result);

Open in new window

Running again, it's now clear that the outcome of the bitwise OR can't get higher then 127.
result = bor | SET;

Open in new window

I do understand the 127 in relation to the binary context, but how thus this limitation exist?
What do i have to change to let the bitwise OR give a result higher then 127?
Comment
Watch Question

ozo
Most Valuable Expert 2014
Top Expert 2015

Commented:
Did you try entering a value greater than 127?
Hi,

I'm not sure if this is the error, on my compiler (I tested in C++) the exact same code produces some other output - but there's one line which makes no sense.
n << 1;

Open in new window

This is just an expression, which evaluates to the result of shifting n one bit to the left, but it doesn't change n - you should replace this by one of these:
n = n << 1;
// or
n <<= 1;

Open in new window

And, BTW, just a hint to this line:
static char bin[9];

Open in new window

The static is not needed and at least useless, it makes the code probably less performant and will probably lead to streange results when the function is used in a multi-threading application.

Hope that helps,

ZOPPO
Distinguished Expert 2019

Commented:
0 OR 1 = 1
1 OR 1 = 1
1 OR 0 = 1

96 = 64 + 32  so any value from 96 to 127 will have 2^5 bit set 00010000
128 + 32 = 160 - > 255 so 160 to 255 will also have 2^5 set

Author

Commented:
@ozo : I didn't, but reading the comment of David, I understand that a value between 128 and 160 also does the trick.
@ZOPPO : That was a typo indeed. I changed it before I displayed the outcome in my question. Thanks for that!

@David : Thanks, but how do I change the code so the value from 96 to 127 will give the correct outcome? Or is that just not possible?
Hm - I did read it again, and I'm not sure what's it what you think is wrong.
95 | 32 = 0x01011111 | 0x00100000 = 0x01111111 = 127
96 | 32 = 0x01100000 | 0x00100000 = 0x01100000 = 96
97 | 32 = 0x01100001 | 0x00100000 = 0x01100001 = 97
...

Open in new window

That's correct ... what did you expect?

Author

Commented:
@Zoppo: I think I did expect the reaction I got from entering 95. So entering 96 would have resulted in 128...I do understand that this is not gonna happen :-)
I'm learning, learning, learning... Thanks!
You're welcome, I'm glad I could help ...

BTW: it's sometimes helpful to have a tool which shows different representations of a number (dec, hex, bin) ... i.e. in Windows the calculator does this in Programmer-Mode.

good luck und best regards,

ZOPPO
Distinguished Expert 2019

Commented:
you seem to think that the OR is adding 32 to any value since the OR'ing does add the 32 bit UNLESS that bit is already set then it does nothing.
when dealing at the bit level you have to think in binary and not in decimal.
000 OR 011 = 011  000 AND 011 = 000
001 OR 011 = 011  001 AND 011 = 001
010 OR 011 = 011  010 AND 011 = 010
011 OR 011 = 011  011 AND 011 = 011
100 OR 011 = 111  100 AND 011 = 000
101 OR 011 = 111  101 AND 011 = 001
110 OR 011 = 111  110 AND 011 = 010
111 OR 011 = 111  111 AND 011 = 011

6 * 2 can be represented as  2 + 2 + 2 + 2 + 2 + 2
6 / 2  can be represented as 6 -2 -2 -2 we keep a count of how many 2's in this case it is 3 before we hit 0 or even quicker just right shift 110 >> 011 = 3
Actually early computers only had a compare if or not 0 and an adder  Subtraction was by invert and add 1 and then add the 2 items together
5 - 3 = 101 - 011 (transformed to 100 then add 1 = 101 )  101 + 101 = 1010 and we ignore the overflow  010 = 2
ozo
Most Valuable Expert 2014
Top Expert 2015

Commented:
If you want result to be higher then 127, then you must have either bor higher than 127 or SET higher than 127.


Without the static, the
  return(bin);
would return an address that was no longer in a valid scope, so the result of  
  printf("\t%s\t%d\n",binbin(bor),bor);
would be undefined.
But I agree that this use of a static address would be poor practice if the  function is to be used in a multi-threading application.

Author

Commented:
Hi guys, thanks for the response and quick and clear help. It really helped.
Ah, sorry - thanks to ozo, I didn't think about the further implications :/ ... seems I'm to spoilt from C++