How to extract one specific bit from a uint16_t variable properly - c++

Long story short, I am currently coding a wrapper in C++ for a C - library which extracts the value of registers on an embedded system. To monitor what happens, I need to read the value of a bit for some registers and make a getter for each of them.
Basically, I would like my method to return one bool from a bit stored into a uint16_t variable. On a 'naive' and uncaffeinated approach I was doing something like that :
bool getBusyDevice(int fd) // fd stands for file descriptor, for each instance of the class
{
uint16_t statusRegVal = 0;
get_commandReg(fd, &statusRegVal); // C-library function to get the value of status register
uint16_t shift = 0; // depends on the bit to access - for reusability
bool Busy = (bool) (statusRegVal >> shift);
return busy;
}
I am not quite happy with the result and I would like to know if there was a 'proper' way to do that...
Thanks a lot for your advice !

The normal way to get just a single bit is to use the bitwise and operator &. Like e.g. statusRegVal & bitValue. If the bit is set then the result will be equal to bitValue, meaning to get a boolean result you could do a simple comparison: statusRegVal & bitValue == bitValue.
So if you want to check if bit zero (which has the value 0x0001) is set, then you could simply do
return statusRegVal & 0x0001 == 0x0001;

For better understanding of what you want, take a look at the following link
Masking: https://en.wikipedia.org/wiki/Mask_(computing)
and
Bit Manipulation: https://en.wikipedia.org/wiki/Bit_manipulation
Conclusion:
If you want to read specific number of bits in variable(register), you should make a MASK with this variable with bits positions.
say you've 2Byte variable (u16Reg) and you want to read bits [5,7] so,
value = ((u16Reg & 0x00A0) >> 5).
In you case, you want to read one bit and return with its status TRUE or FALSE.
value = ((u16Reg & (0x0001 << n)) >> n)
where n is the bit number you want to read.
Lets understand it.
say u16Reg = 0x529D = 0b0101001010011101; bit[0] = 1 and bit[15] = 0; and you want to get bit number 9.
So, First make sure that all bits are zeros except yours (9).
(0b0101001010011101 & (0x0001 << 9)) =
(0b0101001010011101 & 0x0200) =
(0b0101001010011101 & 0b0000001000000000) =
(0b0000001000000000) = 0x0200
this means TRUE in case you mean nonZero is TRUE. But if TRUE means 0x01, you should move this bit to bit[0] as following:
(0x0200 >> 9) = 0x0001 is TRUE
If you can understand this, you can make it simpler like:
value = ((u16Reg >> n) & 0x0001)

Why not to use templates:
template<int SHIFT>
bool boolRegVal(uint16_t val) {
return val & (1 << SHIFT);
}
And then usage:
boolRegVal<4>(statusRegVal);

The casting to bool won't be helpful because it doesn't 1 bit type.
you must clean the rest of the bits, and then check if you've got 0.
You can do something like this:
bool Busy = ((statusRegVal >> shift) & 1) ? true : false;

The standard library provides std::bitset for manipulating bits. Here's an example but am sure you can guess what it does.
#include <bitset>
#include <iostream>
using namespace std;
int main(int, char**){
typedef bitset<sizeof(int)*8> BitsType; //or uint16_t or whatever
BitsType bits(0xDEADBEEF);
for(int i = 0; i < 5; ++i) //access the bits
cout << "bits[" << i << "] = " << bits[i] << '\n';
cout << "bit[3] = " << bits[3] << '\n'; //original
bits.flip(3);
cout << "bit[3] = " << bits[3] << '\n'; //b[3] = !b[3]
return 0;
}
The operator [](size_t) is overloaded to return a reference so you can assign to it too. bits[4] = false for example. And finally, when done playing with your bits :) you can convert back to long (or ulong) or in your case uint16_t value = static_cast<uint16_t>(bits.to_ulong()). Kudos to stdlib.

Related

Translate c++ functions in TypeScript

Given the following functions written in C++:
#define getbit(s,i) ((s)[(i)/8] & 0x01<<(i)%8)
#define setbit(s,i) ((s)[(i)/8] |= 0x01<<(i)%8)
How can I turn them into compatible TypeScript functions?
I came up with:
function setbit(s: string, i: number): number {
return +s[i / 8] | 0x01 << i % 8;
}
function getbit(s: string, i: number): number {
return +s[i / 8] & 0x01 << i % 8;
}
I found out that the a |= b equivalent is a = a | b, but I'm not sure about the getbit function implementation. Also, I don't really understand what those functions are supposed to do. Could someone explain them, please?
Thank you.
EDIT:
Using the ideas from #Thomas, I ended up doing this:
function setBit(x: number, mask: number) {
return x | 1 << mask;
}
// not really get, more like a test
function getBit(x: number, mask: number) {
return ((x >> mask) % 2 !== 0);
}
since I don't really need a string for the binary representation.
Strings ain't a good storage here. And btw, JS Strings use 16bit characters, so you're using only 1/256th of the storage possible.
function setbit(string, index) {
//you could do `index >> 3` but this will/may fail if index > 0xFFFFFFFF
//well, fail as in produce wrong results, not as in throwing an error.
var position = Math.floor(index/8),
bit = 1 << (index&7),
char = string.charCodeAt(position);
return string.substr(0, position) + String.fromCharCode(char|bit) + string.substr(position+1);
}
function getbit(string, index) {
var position = Math.floor(i/8),
bit = 1 << (i&7),
char = string.charCodeAt(position);
return Boolean(char & bit);
}
better would be a (typed) Array.
function setBit(array, index){
var position = Math.floor(index/8),
bit = 1 << (index&7);
array[position] |= bit; //JS knows `|=` too
return array;
}
function getBit(array, index) {
var position = Math.floor(index/8),
bit = 1 << (index&7);
return Boolean(array[position] & bit)
}
var storage = new Uint8Array(100);
setBit(storage, 42);
console.log(storage[5]);
var data = [];
setBit(data, 42);
console.log(data);
works with both, but:
all typed Arrays have a fixed length that can not be changed after memory allocation (creation).
regular arrays don't have a regular type, like 8bit/index or so, limit is 53Bit with floats, but for performance reasons you should stick with up to INT31 (31, not 32), that means 30bits + sign. In this case the JS engine can optimize this thing a bit behind the scenes; reduce memory impact and is a little faster.
But if performance is the topic, use Typed Arrays! Although you have to know in advance how big this thing can get.

Cheking a pattern of bits in a sequence

So basically i need to check if a certain sequence of bits occurs in other sequence of bits(32bits).
The function shoud take 3 arguments:
n right most bits of a value.
a value
the sequence where the n bits should be checked for occurance
The function has to return the number of bit where the desired sequence started. Example chek if last 3 bits of 0x5 occur in 0xe1f4.
void bitcheck(unsigned int source, int operand,int n)
{
int i,lastbits,mask;
mask=(1<<n)-1;
lastbits=operand&mask;
for(i=0; i<32; i++)
{
if((source&(lastbits<<i))==(lastbits<<i))
printf("It start at bit number %i\n",i+n);
}
}
Your loop goes too far, I'm afraid. It could, for example 'find' the bit pattern '0001' in a value ~0, which consists of ones only.
This will do better (I hope):
void checkbit(unsigned value, unsigned pattern, unsigned n)
{
unsigned size = 8 * sizeof value;
if( 0 < n && n <= size)
{
unsigned mask = ~0U >> (size - n);
pattern &= mask;
for(int i = 0; i <= size - n; i ++, value >>= 1)
if((value & mask) == pattern)
printf("pattern found at bit position %u\n", i+n);
}
}
I take you to mean that you want to take source as a bit array, and to search it for a bit sequence specified by the n lowest-order bits of operand. It seems you would want to perform a standard mask & compare; the only (minor) complication being that you need to scan. You seem already to have that idea.
I'd write it like this:
void bitcheck(uint32_t source, uint32_t operand, unsigned int n) {
uint32_t mask = ~((~0) << n);
uint32_t needle = operand & mask;
int i;
for(i = 0; i <= (32 - n); i += 1) {
if (((source >> i) & mask) == needle) {
/* found it */
break;
}
}
}
There are some differences in the details between mine and yours, but the main functional difference is the loop bound: you must be careful to ignore cases where some of the bits you compare against the target were introduced by a shift operation, as opposed to originating in source, lest you get false positives. The way I've written the comparison makes it clearer (to me) what the bound should be.
I also use the explicit-width integer data types from stdint.h for all values where the code depends on a specific width. This is an excellent habit to acquire if you want to write code that ports cleanly.
Perhaps:
if((source&(maskbits<<i))==(lastbits<<i))
Because:
finding 10 in 11 will be true for your old code. In fact, your original condition will always return true when 'source' is made of all ones.

How to check a particular bit of a "long long int" in C++

I'm trying to check a particular bit of a long long integer
long long int val=23355665641326;
int bit_no=32;
if( (val & (1<<bit_no)) == 0)
cout<<bit_no<<"'th bit is not set\n";
else
cout<<bit_no<<"'th bit is set\n";
the binary equivalent of 23355665641326 is -
101010011110111101010001001110110111101101110
^
we see, 32'th bit is set. But my code returns not set :(
how can i check the bit?
Your life would be easy if you use std::bitset instead:
constexpr auto N = CHAR_BIT * sizeof(long long int);
std::bitset<N> val(23355665641326LL);
Now you can test a particular bit as:
if ( val.test(i) ) {
//bit at index i is set!
}
Or you can use the faster — but unsafe — version, as:
if ( val[i] ) {
//bit at index i is set!
}
test() performs bound check and throws std::out_of_range if the index is invalid, whereas operator[] does not, in which case invalid index leads to undefined behavior.
You can use 1LL<<bit_no to check the bit status of a long long int.
As you are dealing with long long int you need to use long long type 1
Because if you use normal 1(int), you can check upto 31 bit
So just change the checking portion like this -
if( (val & (1LL<<bit_no) ) == 0)
^^^
To overcome with the need of adding the suffix to the check simply do something like this:
if(!!((val >> bit_no) & 1))
std::cout << "not set";
else
std::cout << "is set";

C++ Bitset << operator not working. Pointer to bitset variable

I have a set of bitsets pointers in an unordered_map
static unordered_map< size_t, bitset<BITSIZE>* > systemBits;
And my function
template<typename system>
static bitset<BITSIZE> & getBitFor() {
size_t hash = typeid(system).hash_code();
bitset<BITSIZE> * bit = systemBits[hash];
if(bit == NULL) {
bit = new bitset<BITSIZE>(0);
(*bit) << POS++; // tried *bit << POS++ as well;
systemBits[hash] = bit;
}
return *bit;
}
Whereas POS is an int set to 1 at first.
All that I'm trying to do is shift the bitset with the amounts of position per new bitset.
(*bit) << POS++;
However this doesn't seem to work. When I cout the returned bitset all its bits are set to 0.
If I do to the following:
bit->flip();
or
(*bit).flip();
The bitset returned does flip all the 0 to 1.
What gives? Why does the shift operator have no effect at all?
Because you're not assigning the result to anything . You'd have the same problem if you were trying to shift an int.
Also, you've initialized your bitset to zero, and zero shifted by any amount is always zero.

add 1 to c++ bitset

I have a c++ bitset of given length. I want to generate all possible combinations of this bitset for which I thought of adding 1 2^bitset.length times. How to do this? Boost library solution is also acceptable
Try this:
/*
* This function adds 1 to the bitset.
*
* Since the bitset does not natively support addition we do it manually.
* If XOR a bit with 1 leaves it as one then we did not overflow so we can break out
* otherwise the bit is zero meaning it was previously one which means we have a bit
* overflow which must be added 1 to the next bit etc.
*/
void increment(boost::dynamic_bitset<>& bitset)
{
for(int loop = 0;loop < bitset.count(); ++loop)
{
if ((bitset[loop] ^= 0x1) == 0x1)
{ break;
}
}
}
All possible combinations? Just use 64-bit unsigned integer and make your life easier.
Not best, but brute force way, but you can add 1 by converting using to_ulong()
bitset<32> b (13);
b = b.to_ulong() + 1;
Using boost library, you can try the following:
For example, a bitset of length 4
boost::dynamic_bitset<> bitset;
for (int i = 0; i < pow(2.0, 4); i++) {
bitset = boost::dynamic_bitset<>(4, i);
std::cout << bitset << std::endl;
}