What is the meaning of 0b00 and 0b11 in C/C++? [duplicate] - c++

This question already has answers here:
Can I use a binary literal in C or C++?
(24 answers)
Closed 3 years ago.
I have a small question I hope there is a simple answer there. When programming an Arduino in C/C++ the line "DDRB |= 0b00101000;" occurs. While I know DDRB is the Data Direction Register for port B and the meaning of the numbers after "0b00" (which are the slots 13 to 9), I still don't really know what "0b00" means.
In definitions I only read it means HIGH (while 0b11 means LOW) but what does that mean?
Full code:
#include <avr/io.h>
#include <util/delay.h>
int main (void) {
float seconds = 0.5;
int time = 1000 * seconds;
DDRB |= 0b00101000;
while (1) {
PORTB |= 0b00001000;
_delay_ms(time);
PORTB &= 0b11110111;
PORTB |= 0b00100000;
_delay_ms(time);
PORTB &= 0b11011111;
}
return 0;
}

0b means that a number in binary representation is expected.
For Data direction registers, setting the bits to 1 will make the respective lines outputs, and setting to 0 will make them inputs.
The DDRB |= 0b00101000 will do a binary OR operation between the current value of the bits in DDRB with the mask.
This will result in DDRB = 0b××1×1xxx, so that means DDRB will keep the value for lines 7 and 6. This operation basically sets lines 5 and 3 as Output and leaves the rest as they were.

As you tag your question "Arduino", you might be interested that besides the standard c++ 0b... notation the IDE also provides all 8-bit combinations of binary numbers in B00101000 format, with and without leading zeros.
Usually, hex notation (0x28 in your example) is even easier readable, IMO

The line
DDRB |= 0b00101000
basically does a bitwise OR with the mask 0b00101000 and reassigns the results to DDRB.
0b indicates that whatever comes next should be interpreted as binary, so it's easier to see which bits you are masking.
The code is just setting the bits masked as 1 to HIGH and leaving the others unchanged.

Related

C ++ How to change the value of 4 bits in a 32 bit number [duplicate]

This question already has answers here:
How do you set only certain bits of a byte in C without affecting the rest?
(4 answers)
Closed 2 years ago.
I have a 32-bit register that I need to manipulate. But I only need to change bits 12-15, and leave the rest of the bits unchanged.
I want to overwrite whatever is in bits 12-15 with 0x2 or 0b0010.
How can I do this in C++?
Here is an example code I have been trying.
#include <iostream>
#include <bitset>
using namespace std;
int main() {
uint32_t x = 0x4D00D0F0;
x |= 0x2 << 12; // shifting 0x2 12 bits to the left
return 0;
}
My solution only seems to shift a 1 to bit 13, why is that?
Can I shift an entire 4-bit hex number?
Bottom line, I want x = 0x4D0020F0
First, mask the original bits out to make sure they are zeroed and won't interfere with the value, you are going to "or" there:
x & 0xffff0fff
Then "or" the new bits into place:
(x & 0xffff0fff) | (0x2 << 12)
In general x = (x & ~mask) | (y & mask) copies the bits in mask position from y to x.
In OP's case mask = 0xF000 and y = 0x2000.

How to perform bitwise operations on 16bit numbers (Arduino)

I'm working on an Arduino powered Tetris game. To keep track of the pieces that have fallen and become fixed I have an array of bytes
byte theGrid[] = {
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
...
This works great when the well is only 8 LEDs wide, but I need it to be 16 wide. Is there a way to perform bitwise operations on a 16 bit number, like a short? I tried just declaring theGrid as a short, but I'm getting this error no matter what I do.
tetris:62: error: 'B0000000000000000' was not declared in this scope
...leading 'B' only works with 8 bit values (0 to 255)...
from http://arduino.cc/en/pmwiki.php?n=Reference/IntegerConstants
Just use hexadecimal notation, ie. 0x0000 for 2 bytes.
0x signals that it is hex, and every digit (0123456789ABCDEF) replaces 4 bit.
Instead of bitRead and bitSet, you can use following code;
The variable is x and the bit number i, with i=0 is the right-most bit, 1 the next ...):
//set bit to 1
x |= 1<<i;
//set bit to 0
x &= ~(1<<i);
//check if bit is set
if(x & (1<<i))
Eg. x &= ~(1<<3); sets a value B11111111 (in binary representation) to B11110111,
that is 0xff to 0xf7. Btw., x &= ~(1<<3); is equivalent to x &= ~8;

How to set the highest-valued 1 bit to 0 , prefferably in c++ [duplicate]

This question already has answers here:
What's the best way to toggle the MSB?
(4 answers)
Closed 8 years ago.
If, for example, I have the number 20:
0001 0100
I want to set the highest valued 1 bit, the left-most, to 0.
So
0001 0100
will become
0000 0100
I was wondering which is the most efficient way to achieve this.
Preferrably in c++.
I tried substracting from the original number the largest power of two like this,
unsigned long long int originalNumber;
unsigned long long int x=originalNumber;
x--;
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
x++;
x >>= 1;
originalNumber ^= x;
,but i need something more efficient.
The tricky part is finding the most significant bit, or counting the number of leading zeroes. Everything else is can be done more or less trivially with left shifting 1 (by one less), subtracting 1 followed by negation (building an inverse mask) and the & operator.
The well-known bit hacks site has several implementations for the problem of finding the most significant bit, but it is also worth looking into compiler intrinsics, as all mainstream compilers have an intrinsic for this purpose, which they implement as efficiently as the target architecture will allow (I tested this a few years ago using GCC on x86, came out as single instruction). Which is fastest is impossible to tell without profiling on your target architecture (fewer lines of code, or fewer assembly instructions are not always faster!), but it is a fair assumption that compilers implement these intrinsics not much worse than you'll be able to implement them, and likely faster.
Using an intrinsic with a somewhat intellegible name may also turn out easier to comprehend than some bit hack when you look at it 5 years from now.
Unluckily, although a not entirely uncommon thing, this is not a standardized function which you'd expect to find in the C or C++ libraries, at least there is no standard function that I'm aware of.
For GCC, you're looking for __builtin_clz, VisualStudio calls it _BitScanReverse, and Intel's compiler calls it _bit_scan_reverse.
Alternatively to counting leading zeroes, you may look into what the same Bit Twiddling site has under "Round up to the next power of two", which you would only need to follow up with a right shift by 1, and a NAND operation. Note that the 5-step implementation given on the site is for 32-bit integers, you would have to double the number of steps for 64-bit wide values.
#include <limits.h>
uint32_t unsetHighestBit(uint32_t val) {
for(uint32_t i = sizeof(uint32_t) * CHAR_BIT - 1; i >= 0; i--) {
if(val & (1 << i)) {
val &= ~(1 << i);
break;
}
}
return val;
}
Explanation
Here we take the size of the type uint32_t, which is 4 bytes. Each byte has 8 bits, so we iterate 32 times starting with i having values 31 to 0.
In each iteration we shift the value 1 by i to the left and then bitwise-and (&) it with our value. If this returns a value != 0, the bit at i is set. Once we find a bit that is set, we bitwise-and (&) our initial value with the bitwise negation (~) of the bit that is set.
For example if we have the number 44, its binary representation would be 0010 1100. The first set bit that we find is bit 5, resulting in the mask 0010 0000. The bitwise negation of this mask is 1101 1111. Now when bitwise and-ing & the initial value with this mask, we get the value 0000 1100.
In C++ with templates
This is an example of how this can be solved in C++ using a template:
#include <limits>
template<typename T> T unsetHighestBit(T val) {
for(uint32_t i = sizeof(T) * numeric_limits<char>::digits - 1; i >= 0; i--) {
if(val & (1 << i)) {
val &= ~(1 << i);
break;
}
}
return val;
}
If you're constrained to 8 bits (as in your example), then just precalculate all possible values in an array (byte[256]) using any algorithm, or just type it in by hand.
Then you just look up the desired value:
x = lookup[originalNumber]
Can't be much faster than that. :-)
UPDATE: so I read the question wrong.
But if using 64 bit values, then break it apart into 8 bytes, maybe by casting it to a byte[8] or overlaying it in a union or something more clever. After that, find the first byte which are not zero and do as in my answer above with that particular byte. Not as efficient I'm afraid, but still it is at most 8 tests (and in average 4.5) + one lookup.
Of course, creating a byte[65536} lookup will double the speed.
The following code will turn off the right most bit:
bool found = false;
int bit, bitCounter = 31;
while (!found) {
bit = x & (1 << bitCounter);
if (bit != 0) {
x &= ~(1 << bitCounter);
found = true;
}
else if (bitCounter == 0)
found = true;
else
bitCounter--;
}
I know method to set more right non zero bit to 0.
a & (a - 1)
It is from Book: Warren H.S., Jr. - Hacker's Delight.
You can reverse your bits, set more right to zero and reverse back. But I do now know efficient way to invert bits in your case.

Can someone please explain this line of code to me? [duplicate]

This question already has answers here:
<< operator in C++?
(3 answers)
Closed 9 years ago.
I'm reading values from an accelerometer and saving them in a buffer called 'values'. Each accelerometer reading is 10 bits long, but the values are read in as bytes, so eah accelerometer reading is actually two bytes or two values in the 'values' buffer. This is sample code on how to combine those two bytes to get the one value:
x = ((int)values[1]<<8)|(int)values[0];
I get that I'm combining values[1] and values[2] and I'm pretty sure the (int) part is type casting those parts as integers (although I'm not sure why). The parts that have me really confused are <<8 and the vertical bar |. What are these two parts doing?
Thanks for any explanation and help you can give!
It's a bitmask.
You are left shifting (<<) the value in values[1] by 8 bit-positions. and then ORing (|) it to the value in values[0].
Please take some values and try to work through them. You will understand it better.
Here's a link for more reading and bit-manipulation examples.
This line of code combines two char into a int in a way that first char is moved 8 bits.
For example, value[0] = 5, value[1] = 1, then the read in value should be, 128 + 5 = 133. Because the high byte 1 means 128. Another way to look at it is:
x = ((int)values[1]<<8) + (int)values[0];
Replace or with +, it will be more readable. Hope this helps.
Take for example a 10-bit reading of 0101010111 in binary.
The lower 8 bits go to values[0] = 01010111 in binary (= 87 decimal).
The higher 2 bits go to values[1] = 01.
To recover the original 10-bit number from values:
(int)values[1] << 8 --> 01 << 8 --> 0100000000
values[1] is converted to a int (typically 32 bits) and then shifted left << 8 bits.
((int)values[1]<<8) | (int)values[0] --> 0100000000 | 01010111
or in vertical notation to express a bitwise-or:
0100000000
| 01010111
------------
0101010111
QED
The << operator shifts the bits in the second byte left by 8 bits so for example 0000000011111111 becomes 1111111100000000. The | is the binary "or" operator that combines the two bits in every position making it 1 if either bit or both bits are 1.
You have 2 bytes (1 byte = 8 bits) and you are trying to read in a 10 bit value, which is why you need 2 bytes instead of just using 1. When you are reading in the value you need to cast the 2 bytes to int so you can treat them like and integer value, but there is an issue, if value[1] is 3 (00000011) and the next byte value[0] is 227 (11100011) you can get a proper reading if you add them so you need to bit shift value[1] left by 8.
When you bit shift a unsigned char/char/byte by 8 you end up with 0, so you need to cast both value[1] and value[0] to an int so when you do the bit shift you end up with 768 (00000011 00000000) now you | that with value [0] and you end up with
(00000011 00000000 | 00000000 11100011) = (00000011 11100011) = 995
note I am only using 16bit ints so the example isn't full of a bunch of 0s.
If you have access to a programming calculator it can help you understand why you need to cast these byte values to ints, it can also just help you with casting in general. I would sugest playing around with the windows Calculator app for a bit if you have access to it. In order to get it into the programmer view go to view->programmer.

Bitwise NOT operator returning unexpected and negative value? [duplicate]

This question already has answers here:
Why is the output -33 for this code snippet
(3 answers)
Closed 9 years ago.
I'm trying to get the value of an integer using Bitwise NOT, but i'm not getting what i expected.
#include <stdio.h>
int main(){
int i = 16;
int j = ~i;
printf("%d", j);
return 0;
}
Isn't 16 supposed to be:
00000000000000000000000000010000
So ~16 is supposed to be:
11111111111111111111111111101111
Why i'm not getting what i expected and why the result is negative?
This is what i'm trying to do:
I have a number for exemple 27 which is:
00000000000000000000000000011011
And want to check every bit if it's 1 or 0.
So i need to get for exemple this value
11111111111111111111111111110111
The use second one to check if the 3rd bit of the first is set to 1.
Although there are pedantic points which can be made about compiler behaviour, the simple answer is that a signed int with the top bit set is a negative number.
So if you do something which sets the top bit of an int (a signed int, not an unsigned one), then ask the tools/library to show you the value of that int, you'll see a negative number.
This is not a universal truth, but it's a good approximation to it for most modern systems.
Note that it's printf which is making the representation here - because %d formats numbers as signed. %u may give the result you're expecting. Just changing the types of the variables won't be enough, because printf doesn't know anything about the types of its arguments.
I would say that as a general rule of thumb, if you're doing bit-twiddling, then use unsigned ints and display them in hexadecimal. Life will be simpler that way, and it most generally fits with the intent. (Fancy accelerated maths tricks are an obvious exception)
And want to check every bit if it's 1 or 0.
To check an individual bit, you don't NOT the number, you AND it with an appropriate bit mask:
if ((x & 1) != 0) ... // bit 0 is 1
if ((x & 2) != 0) ... // bit 1 is 1
if ((x & 4) != 0) ... // bit 2 is 1
if ((x & 8) != 0) ... // bit 3 is 1
...
if ((x & (1 << n)) != 0) ... // bit n is 1
...
if ((x & 0x80000000) != 0) ... // bit 31 is 1
If you want to get ones' complement of a number, you need to put that number into an unsigned variable and show it as so.
In C it would be:
unsigned int x = ~16;
printf("%u\n", x);
and you will get 4294967279.
But if you are just trying to get the negative number of a certain one, put the - operator before it.
EDIT: To check whether a bit is 0 or 1, you have to use the bitwise AND.
In two-complement arithmetic to get a reverse number (for example for value 16 to get value -16) you need reverse each bit and add 1.
In your example, to get -16 from 16 that is represented as
00000000000000000000000000010000
you need reverse each bit. You will get
11111111111111111111111111101111
Now you must add 1 and you will get
11111111111111111111111111110000
As you can see if you add these two values, you will get 0. It proves that you did all correctly.