Go Down

### Topic: working with bitwise (Read 2465 times)previous topic - next topic

#### Wazzled

##### Apr 11, 2012, 03:22 am
Hi, in a reply by Nick Gammon on this thread http://arduino.cc/forum/index.php/topic,100085.0.html he uses

Code: [Select]
`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

#1
##### Apr 11, 2012, 04:09 am

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.

#### Morris Dovey

#2
##### Apr 11, 2012, 04:17 am
Sure - I'm going to make more variables to make it easy to follow:

Code: [Select]
`   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.
There's always a better way!

#### Wazzled

#3
##### Apr 11, 2012, 04:31 am
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?

#### Morris Dovey

#4
##### Apr 11, 2012, 04:43 am
The AND operation (&) result one only when both operands are 1, and zero otherwise:

Code: [Select]
`     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.
There's always a better way!

#### Wazzled

#5
##### Apr 11, 2012, 04:51 amLast Edit: Apr 11, 2012, 05:09 am by Wazzled Reason: 1
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.

#### Grumpy_Mike

#6
##### Apr 11, 2012, 05:21 am
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.

#### Jack Christensen

#7
##### Apr 11, 2012, 05:22 am
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!  XD

#### Wazzled

#8
##### Apr 11, 2012, 05:43 am
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.

#### Techone

#9
##### Apr 11, 2012, 06:05 am
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.

#### Grumpy_Mike

#10
##### Apr 11, 2012, 10:37 am
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

#### Wazzled

#11
##### Apr 11, 2012, 01:05 pmLast Edit: Apr 11, 2012, 02:38 pm by Wazzled Reason: 1
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

#### AWOL

#12
##### Apr 11, 2012, 01:34 pm
Quote
I thought binary went from left to right like

No, like decimal and hexadecimal, the powers of the base decrease left to right.
"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.

#### Wazzled

#13
##### Apr 11, 2012, 02:35 pm
So does that mean my above example is right?

#### Morris Dovey

#14
##### Apr 11, 2012, 04:04 pm
No - powers increase from right to left:

Quote
27+26+25+24+23+22+21+20
There's always a better way!

Go Up

Please enter a valid email to subscribe