Pages: [1] 2   Go Down
 Author Topic: working with bitwise  (Read 647 times) 0 Members and 1 Guest are viewing this topic.
Northern Ireland
Offline
Newbie
Karma: 0
Posts: 45
Arduino rocks
 « on: April 10, 2012, 08:22:57 pm » Bigger Smaller Reset

Hi, in a reply by Nick Gammon on this thread http://arduino.cc/forum/index.php/topic,100085.0.html he uses

Code:
void showbin (const byte c)
{
for (int i = 7; i >= 0; i--)
Serial.write ((c >> i) & 1 | '0');
Serial.println ();
}

could someone please explain what exactly is happening bitwise in the call to Serial.write?

Thanks
 Logged

Global Moderator
Dallas
Offline
Shannon Member
Karma: 129
Posts: 10379
 « Reply #1 on: April 10, 2012, 09:09:41 pm » Bigger Smaller Reset

Assume c is 1001 0010 in binary.  The first pass through the for-loop...

i =7

((c >> i) & 1 | '0')  --> The zero character ('0') can also be interpreted as the byte value 0x30 or a bit value of 00110000.  I'll use the bit value until the end.

((10010010 >> 7) & 1 | 00110000)  --> The double greater-than is a bit shift to the right.  The bits in c are shifted 7 bits to the right.  We're left with the left-most bit...

((00000001) & 1 | 00110000)  --> The ampersand is a bitwise-and.  If both bits are one the result is one otherwise the result is zero...

(00000001 | 00110000)  --> The bar is a bitwise-or.  If either bit is a one the result is one otherwise the result is zero...

00110001  --> Which is also 0x31.  Which is also '1'.  The character '1' is sent to the serial port.

i = 6

((c >> i) & 1 | '0')

((10010010 >> 6) & 1 | 00110000)

((00000010) & 1 | 00110000)

(00000000 | 00110000)

00110000  --> Which is also 0x30.  Which is also '0'.  The character '0' is sent to the serial port.

i = 0

((c >> i) & 1 | '0')

((10010010 >> 0) & 1 | 00110000)  --> Shifting by zero bits results in the same value...

((10010010) & 1 | 00110000)

(00000000 | 00110000)

00110000  --> Which is also 0x30.  Which is also '0'.  The character '0' is sent to the serial port.
 Logged

West Des Moines, Iowa USA
Offline
Sr. Member
Karma: 2
Posts: 429
 « Reply #2 on: April 10, 2012, 09:17:57 pm » Bigger Smaller Reset

Sure - I'm going to make more variables to make it easy to follow:

Code:
unsigned char a = c >> i;   // moves the bit of interest into the rightmost position
unsigned char b = a & 1;    // resets all bits except the rightmost
unsigned char d = b | '0';  // converts the value (0 or 1) to a character '0' or '1'
Serial.write(d);            // writes the character to the Serial connection

Nick's way of writing this avoids the need for the intermediate variables.
 Logged

There's always a better way!

Northern Ireland
Offline
Newbie
Karma: 0
Posts: 45
Arduino rocks
 « Reply #3 on: April 10, 2012, 09:31:59 pm » Bigger Smaller Reset

I can see whats happening in most of it now but still not sure what bits are being compared by:

((00000001) & 1 | 00110000)

The OR operation seems to be the last performed so ignoring that leaves 00000001 & 1

how does that reset all the bits except the rightmost?
 Logged

West Des Moines, Iowa USA
Offline
Sr. Member
Karma: 2
Posts: 429
 « Reply #4 on: April 10, 2012, 09:43:55 pm » Bigger Smaller Reset

The AND operation (&) result one only when both operands are 1, and zero otherwise:

Code:
XXXXXXXM
& 00000001
--------
0000000M

so that whatever M is (0 or 1) in the first operand, it will appear in the same position in the result, and all other bits of the result will be zeros.
 Logged

There's always a better way!

Northern Ireland
Offline
Newbie
Karma: 0
Posts: 45
Arduino rocks
 « Reply #5 on: April 10, 2012, 09:51:10 pm » Bigger Smaller Reset

Sorry for not getting this but what is the second operand?

I get one of them is 00000001 that we got from the bitwise right shift, but what are we comparing this too for the AND.  Why is the other side of the AND a 1, im expecting that to be another byte.

EDIT: Wow it's 04:10 maybe thats the problem lol.
 « Last Edit: April 10, 2012, 10:09:14 pm by Wazzled » Logged

Manchester (England England)
Offline
Brattain Member
Karma: 299
Posts: 26025
Solder is electric glue
 « Reply #6 on: April 10, 2012, 10:21:03 pm » Bigger Smaller Reset

Quote
what are we comparing this too for the AND
There is no compairing going on, these are digital logical operations on the bit level. You are ANDing the value on the right with the result of what has been evaluated to the left of it.
 Logged

Grand Blanc, MI, USA
Offline
Karma: 47
Posts: 2570
"We're a proud service of the Lost Electricity Reclamation Agency"
 « Reply #7 on: April 10, 2012, 10:22:57 pm » Bigger Smaller Reset

LOL Nick must be working up to the IOCCC.

I might have used Serial.println(c, BIN);

Actually I think it is a very good exercise, though!

 Logged

Get the infamous "One Million Ohms" board at tINDIE.com: http://tinyurl.com/BuyMohms

Northern Ireland
Offline
Newbie
Karma: 0
Posts: 45
Arduino rocks
 « Reply #8 on: April 10, 2012, 10:43:04 pm » Bigger Smaller Reset

How can we do an AND without comparing two bit patterns?

11001100 & 01010101 = 01000100 comparing both bit patterns and if its a 1 in both its a 1 in the result.
 Logged

Offline
Edison Member
Karma: 2
Posts: 1233
"Keep it R.E.I.L. - "Research, Experiment, Investigate and Learn"
 « Reply #9 on: April 10, 2012, 11:05:04 pm » Bigger Smaller Reset

The AND operand is use to isolate a bit or multiple bits. A useful technique.

Quote
11001100 & 01010101 = 01000100 comparing both bit patterns and if its a 1 in both its a 1 in the result.

Here you trying to do :     1100 1100                  AND Gate
&  0101 0101                  A   B   Out
-------------------                 ------------
0100 0100                   0   0    0
0   1    0
1   0    0
1   1    1

Now Let OR :    1100 1100                   OR Gate
| 0101 0101                   A     B   Out
--------------                  --------------
1101 1101                   0     0    0
0     1    1
1     0    1
1     1    1

AND will isolate the bits you want. And OR simply "placed" the bits.
 Logged

Manchester (England England)
Offline
Brattain Member
Karma: 299
Posts: 26025
Solder is electric glue
 « Reply #10 on: April 11, 2012, 03:37:29 am » Bigger Smaller Reset

Quote
How can we do an AND without comparing two bit patterns
We do not compair the bit patterns we perform a function with them. You do not say a subtraction is a result of compairing two bit patterns.

In computing terms a compair is an operation that involves subtracting two values and doing nothing with the result but leaving the status register bit flags to reflect the result.
In C this is done by the == operation
 Logged

Northern Ireland
Offline
Newbie
Karma: 0
Posts: 45
Arduino rocks
 « Reply #11 on: April 11, 2012, 06:05:31 am » Bigger Smaller Reset

Ok so, I think I've been getting the binary wrong.  I thought binary went from left to right like

1 2 4 8 16 32 64 128 I'm now thinking this is wrong and its right to left.

If its right to left, that means to keep say the second and sixth(left to right) bit in the following I would AND it with 68

0111 0111 & 68
0100 0100

 « Last Edit: April 11, 2012, 07:38:23 am by Wazzled » Logged

Global Moderator
UK
Online
Brattain Member
Karma: 143
Posts: 19368
I don't think you connected the grounds, Dave.
 « Reply #12 on: April 11, 2012, 06:34:04 am » Bigger Smaller Reset

Quote
I thought binary went from left to right like
No, like decimal and hexadecimal, the powers of the base decrease left to right.
 Logged

Pete, it's a fool looks for logic in the chambers of the human heart.

Northern Ireland
Offline
Newbie
Karma: 0
Posts: 45
Arduino rocks
 « Reply #13 on: April 11, 2012, 07:35:36 am » Bigger Smaller Reset

So does that mean my above example is right?
 Logged

West Des Moines, Iowa USA
Offline
Sr. Member
Karma: 2
Posts: 429
 « Reply #14 on: April 11, 2012, 09:04:35 am » Bigger Smaller Reset

No - powers increase from right to left:

Quote
27+26+25+24+23+22+21+20
 Logged

There's always a better way!

 Pages: [1] 2   Go Up