Pages: [1] 2   Go Down
Author Topic: working with bitwise  (Read 1364 times)
0 Members and 1 Guest are viewing this topic.
Northern Ireland
Offline Offline
Newbie
*
Karma: 0
Posts: 45
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset 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 Offline
Shannon Member
*****
Karma: 212
Posts: 13083
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset 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 Offline
Sr. Member
****
Karma: 2
Posts: 428
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset 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 Offline
Newbie
*
Karma: 0
Posts: 45
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset 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 Offline
Sr. Member
****
Karma: 2
Posts: 428
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset 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 Offline
Newbie
*
Karma: 0
Posts: 45
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset 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 Offline
Brattain Member
*****
Karma: 639
Posts: 34725
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset 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 Offline
Faraday Member
**
Karma: 95
Posts: 4094
CODE is a mass noun and should not be used in the plural or with an indefinite article.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset 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!  smiley-lol

Logged

MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Northern Ireland
Offline Offline
Newbie
*
Karma: 0
Posts: 45
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset 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

Toronto, Canada
Offline Offline
Edison Member
*
Karma: 2
Posts: 1234
"Keep it R.E.I.L. - "Research, Experiment, Investigate and Learn"
View Profile
 Bigger Bigger  Smaller Smaller  Reset 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 Offline
Brattain Member
*****
Karma: 639
Posts: 34725
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset 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 Offline
Newbie
*
Karma: 0
Posts: 45
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset 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

please let that be right
« Last Edit: April 11, 2012, 07:38:23 am by Wazzled » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 310
Posts: 26626
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset 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." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Northern Ireland
Offline Offline
Newbie
*
Karma: 0
Posts: 45
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So does that mean my above example is right?
Logged

West Des Moines, Iowa USA
Offline Offline
Sr. Member
****
Karma: 2
Posts: 428
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset 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
Jump to: