Avatar of CroetOne
CroetOne
Flag for Netherlands asked on

The bitwise OR in C

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?
C

Avatar of undefined
Last Comment
Zoppo

8/22/2022 - Mon
ozo

Did you try entering a value greater than 127?
Zoppo

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
David Johnson, CD

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
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
CroetOne

ASKER
@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?
ASKER CERTIFIED SOLUTION
Zoppo

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
CroetOne

ASKER
@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!
Zoppo

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
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
David Johnson, CD

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

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.
CroetOne

ASKER
Hi guys, thanks for the response and quick and clear help. It really helped.
This is the best money I have ever spent. I cannot not tell you how many times these folks have saved my bacon. I learn so much from the contributors.
rwheeler23
Zoppo

Ah, sorry - thanks to ozo, I didn't think about the further implications :/ ... seems I'm to spoilt from C++