How to do bitmasking for unsigned long int? - c++

I am working on branch predicter implementation in that I need to create a Branch history register (BHR) which stores 1111 into the first 4 bits of an unsigned int, after every prediction. We will get output from Finite-state machine and that is updated into the BHR using left-shift. Can you explain for me how to do that?
Here's what I've tried:
struct BHR
{
long int BHR_index;
unsigned input = 0b1111u, n_bits = 4u, *bits =new unsigned[n_bits], bit = 0;
};
int main(int argc, char** argv)
{
long int table_size = 1227;
BHR *table = new BHR[table_size];
for(int k = 0;k<=table_size;k++)
{
for(table->bit = 0; table ->bit < table ->n_bits; ++table->bit)
table[k].bits[table -> bit] = (table -> input >> table ->bit)&1;
}
free(table->bits);
}
I did bit masking like this but I am getting thread 1: EXC_BAD_ACCESS (code=1, address=0x0) error in Xcode. Can anyone please help me.

If by "starting 4 bits" you mean the low (least significant) 4 bits, then this mask will clear all others, leaving those 4 bits intact:
unsigned long int someValue = 12345;
unsigned long int low4bits = someValue & 0xF;
This AND mask (& operator) works by clearing all bits in the destination that aren't set in both operands. So, as the value of 0xF in binary is ...0001111, all other bits will be cleared.
If you want the high (most significant) 4 bits, then you need to know the size of unsigned long int (although see below). If (as is common) this is 32-bits, then the mask you need will be as follows:
unsigned long int someValue = 12345;
unsigned long int high4bits = someValue & 0xF0000000;
Feel free to ask for further explanation and/or clarification.
EDIT:
Actually, there is a way to get the mask for the high 4 bits of an unsigned long int even if you don't know its actual size, but it maybe a bit confusing. The code below is not the most 'efficient' way, perhaps; rather, it is designed to illustrate the process:
unsigned long int zeroValue = 0; // All bits are clear.
unsigned long int notZero = ~zeroValue; // ~ inverts all bits, so now all set
unsigned long int top4Clear = notZero >> 4; // shift set bits by 4, and zero-pad top 4
unsigned long int top4Mask = ~top4Clear; // Again, the ~ operator inverts all bits
With this top4Mask value, we can now clear all but the high (most significant) bits:
unsigned long int someValue = 12345;
unsigned long int high4bits = someValue & top4Mask;

Another way is to use bit-fields that do the bit masking for you:
struct ulong4b {
unsigned long value : 4;
};
int main() {
ulong4b a;
a.value = 1; // Stores the lower 4 bits only.
unsigned long value = a.value; // Reads the lower 4 bits only.
}

I think that this macro will help you if you want to extract bits from a number :
#define GET_BITS(number, offbits, nbits) (((number) >> (offbits)) & ((1 << (nbits)) - 1))
int x = 12345;
int last4bits = GET_BITS(x, 0, 4); // last4bits = x & 0x0000000F;
int first4bits = GET_BITS(x, 32 - 4, 4); // first4bits = x & 0xF0000000;

Related

both signed and unsigned as function parameter

I have functions to read data from an EEPROM. When I want to read a short, regardless of it being signed or unsigned, I know I have to read 2 bytes. Same principle goes when I want to read an integer: I have to read 4 bytes, regardless of it being signed or unsigned.
Thus I wrote 4 functions: one that reads a short, one that reads an unsigned short, one that reads an int, one that reads an unsigned int, etc.
Usage looks like this :
// define a default value at zero
uint16_t API_PORT = 0;
// retrieve the API port, that would be between 0 to 65535, saved on the EEPROM
i2cReadUnsignedShortFromExternalEEPROM(I2C_ADDR_EEPROM, 12345, &API_PORT);
// the function
void i2cReadUnsignedShortFromExternalEEPROM(int i2cAddressOfExternalEEPROM, unsigned int atAdress, uint16_t *number) {
byte firstByte = i2cReadByteFromExternalEEPROM(i2cAddressOfExternalEEPROM, atAdress);
byte secondByte = i2cReadByteFromExternalEEPROM(i2cAddressOfExternalEEPROM, atAdress + 1);
*number = (firstByte << 8) + secondByte;
}
The function to read a SIGNED short is almost exactly the same, except the third parameter :
void i2cReadShortFromExternalEEPROM(int i2cAddressOfExternalEEPROM, unsigned int atAdress, short *number) {
byte firstByte = i2cReadByteFromExternalEEPROM(i2cAddressOfExternalEEPROM, atAdress);
byte secondByte = i2cReadByteFromExternalEEPROM(i2cAddressOfExternalEEPROM, atAdress + 1);
*number = (firstByte << 8) + secondByte;
}
Eventhough everything works fine, it bothers me as it introduces a lot of redundancy in my code.
Is there a way to refactor those two similar functions into just one?
The function would need to work in both following pseudocode scenarios :
unsigned short myUnsignedVar = 0;
myNewMethod(I2C_ADDR_EEPROM, 10, &myUnsignedVar);
// myUnsignedVar now holds value of 65000
signed short mySignedVar = 0;
myNewMethod(I2C_ADDR_EEPROM, 12, &mySignedVar);
// mySignedVar now holds value of -123
In other words, I want to make it so that the function accepts both signed and unsigned as 3rd parameter.
I'm new to C++
Following #Taekahn 's comment regarding function templates, my function now looks like this :
template <typename T>
void i2cReadShortFromExternalEEPROM(int i2cAddressOfExternalEEPROM, unsigned int atAddress, T *number) {
byte firstByte = i2cReadByteFromExternalEEPROM(i2cAddressOfExternalEEPROM, atAddress);
byte secondByte = i2cReadByteFromExternalEEPROM(i2cAddressOfExternalEEPROM, atAddress + 1);
*number = (firstByte << 8) + secondByte;
}
It seems to work fine (tested).
Example of usage :
i2cReadShortFromExternalEEPROM<uint16_t>(I2C_ADDR_EEPROM, some_page, &API_PORT); // 443
i2cReadShortFromExternalEEPROM<short>(I2C_ADDR_EEPROM, some_page, &DEPTH); // -12345
Thank you for your guidance.

How to grab specific bits from a 256 bit message?

I'm using winsock to receive udp messages 256 bits long. I use 8 32-bit integers to hold the data.
int32_t dataReceived[8];
recvfrom(client, (char *)&dataReceived, 8 * sizeof(int), 0, &fromAddr, &fromLen);
I need to grab specific bits like, bit #100, #225, #55, etc. So some bits will be in dataReceived[3], some in dataReceived[4], etc.
I was thinking I need to bitshift each array, but things got complicated. Am I approaching this all wrong?
Why are you using int32_t type for buffer elements and not uint32_t?
I usually use something like this:
int bit_needed = 100;
uint32_t the_bit = dataReceived[bit_needed>>5] & (1U << (bit_needed & 0x1F));
Or you can use this one (but it won't work for sign in signed integers):
int bit_needed = 100;
uint32_t the_bit = (dataReceived[bit_needed>>5] >> (bit_needed & 0x1F)) & 1U;
In other answers you can access only lowes 8bits in each int32_t.
When you count bits and bytes from 0:
int bit_needed = 100;
So:
int byte = int(bit_needed / 8);
int bit = bit_needed % 8;
int the_bit = dataReceived[byte] & (1 << bit);
If the recuired bit contains 0, then the_bit will be zero. If it's 1, then the_bit will hold 2 to the power of that bit ordinal place within the byte.
You can make a small function to do the job.
uint8_t checkbit(uint32_t *dataReceived, int bitToCheck)
{
byte = bitToCheck/32;
bit = bitToCheck - byte*32;
if( dataReceived[byte] & (1U<< bit))
return 1;
else
return 0;
}
Note that you should use uint32_t rather than int32_t, if you are using bit shifting. Signed integer bit shifts lead to unwanted results, especially if the MSbit is 1.
You can use a macro in C or C++ to check for specific bit:
#define bit_is_set(var,bit) ((var) & (1 << (bit)))
and then a simple if:
if(bit_is_set(message,29)){
//bit is set
}

Converting 24 bit integer (2s complement) to 32 bit integer in C++

The dataFile.bin is a binary file with 6-byte records. The first 3
bytes of each record contain the latitude and the last 3 bytes contain
the longitude. Each 24 bit value represents radians multiplied by
0X1FFFFF
This is a task I've been working on. I havent done C++ in years so its taking me way longer than I thought it would -_-. After googling around I saw this algorthim which made sense to me.
int interpret24bitAsInt32(byte[] byteArray) {
int newInt = (
((0xFF & byteArray[0]) << 16) |
((0xFF & byteArray[1]) << 8) |
(0xFF & byteArray[2])
);
if ((newInt & 0x00800000) > 0) {
newInt |= 0xFF000000;
} else {
newInt &= 0x00FFFFFF;
}
return newInt;
}
The problem is a syntax issue I am restricting to working by the way the other guy had programmed this. I am not understanding how I can store the CHAR "data" into an INT. Wouldn't it make more sense if "data" was an Array? Since its receiving 24 integers of information stored into a BYTE.
double BinaryFile::from24bitToDouble(char *data) {
int32_t iValue;
// ****************************
// Start code implementation
// Task: Fill iValue with the 24bit integer located at data.
// The first byte is the LSB.
// ****************************
//iValue +=
// ****************************
// End code implementation
// ****************************
return static_cast<double>(iValue) / FACTOR;
}
bool BinaryFile::readNext(DataRecord &record)
{
const size_t RECORD_SIZE = 6;
char buffer[RECORD_SIZE];
m_ifs.read(buffer,RECORD_SIZE);
if (m_ifs) {
record.latitude = toDegrees(from24bitToDouble(&buffer[0]));
record.longitude = toDegrees(from24bitToDouble(&buffer[3]));
return true;
}
return false;
}
double BinaryFile::toDegrees(double radians) const
{
static const double PI = 3.1415926535897932384626433832795;
return radians * 180.0 / PI;
}
I appreciate any help or hints even if you dont understand a clue or hint will help me alot. I just need to talk to someone.
I am not understanding how I can store the CHAR "data" into an INT.
Since char is a numeric type, there is no problem combining them into a single int.
Since its receiving 24 integers of information stored into a BYTE
It's 24 bits, not bytes, so there are only three integer values that need to be combined.
An easier way of producing the same result without using conditionals is as follows:
int interpret24bitAsInt32(byte[] byteArray) {
return (
(byteArray[0] << 24)
| (byteArray[1] << 16)
| (byteArray[2] << 8)
) >> 8;
}
The idea is to store the three bytes supplied as an input into the upper three bytes of the four-byte int, and then shift it down by one byte. This way the program would sign-extend your number automatically, avoiding conditional execution.
Note on portability: This code is not portable, because it assumes 32-bit integer size. To make it portable use <cstdint> types:
int32_t interpret24bitAsInt32(const std::array<uint8_t,3> byteArray) {
return (
(const_cast<int32_t>(byteArray[0]) << 24)
| (const_cast<int32_t>(byteArray[1]) << 16)
| (const_cast<int32_t>(byteArray[2]) << 8)
) >> 8;
}
It also assumes that the most significant byte of the 24-bit number is stored in the initial element of byteArray, then comes the middle element, and finally the least significant byte.
Note on sign extension: This code automatically takes care of sign extension by constructing the value in the upper three bytes and then shifting it to the right, as opposed to constructing the value in the lower three bytes right away. This additional shift operation ensures that C++ takes care of sign-extending the result for us.
When an unsigned char is casted to an int the higher order bits are filled with 0's
When a signed char is casted to a casted int, the sign bit is extended.
ie:
int x;
char y;
unsigned char z;
y=0xFF
z=0xFF
x=y;
/*x will be 0xFFFFFFFF*/
x=z;
/*x will be 0x000000FF*/
So, your algorithm, uses 0xFF as a mask to remove C' sign extension, ie
0xFF == 0x000000FF
0xABCDEF10 & 0x000000FF == 0x00000010
Then uses bit shifts and logical ands to put the bits in their proper place.
Lastly checks the most significant bit (newInt & 0x00800000) > 0 to decide if completing with 0's or ones the highest byte.
int32_t upperByte = ((int32_t) dataRx[0] << 24);
int32_t middleByte = ((int32_t) dataRx[1] << 16);
int32_t lowerByte = ((int32_t) dataRx[2] << 8);
int32_t ADCdata32 = (((int32_t) (upperByte | middleByte | lowerByte)) >> 8); // Right-shift of signed data maintains signed bit

How to convert an array of bits to a char

I am trying to edit each byte of a buffer by modifying the LSB(Least Significant Bit) according to some requirements.
I am using the unsigned char type for the bytes, so please let me know IF that is correct/wrong.
unsigned char buffer[MAXBUFFER];
Next, i'm using this function
char *uchartob(char s[9], unsigned char u)
which modifies and returns the first parameter as an array of bits. This function works just fine, as the bits in the array represent the second parameter.
Here's where the hassle begins. I am going to point out what I'm trying to do step by step so you guys can let me know where i'm taking the wrong turn.
I am saving the result of the above function (called for each element of the buffer) in a variable
char binary_byte[9]; // array of bits
I am testing the LSB simply comparing it to some flag like above.
if (binary_byte[7]==bit_flag) // i go on and modify it like this
binary_byte[7]=0; // or 1, depending on the case
Next, I'm trying to convert the array of bits binary_byte (it is an array of bits, isn't it?) back into a byte/unsigned char and update the data in the buffer at the same time. I hope I am making myself clear enough, as I am really confused at the moment.
buffer[position_in_buffer]=binary_byte[0]<<7| // actualize the current BYTE in the buffer
binary_byte[1]<<6|
binary_byte[2]<<5|
binary_byte[3]<<4|
binary_byte[4]<<3|
binary_byte[5]<<2|
binary_byte[6]<<1|
binary_byte[7];
Keep in mind that the bit at the position binary_byte[7] may be modified, that's the point of all this.
The solution is not really elegant, but it's working, even though i am really insecure of what i did (I tried to do it with bitwise operators but without success)
The weird thing is when I am trying to print the updated character from the buffer. It has the same bits as the previous character, but it's a completely different one.
My final question is : What effect does changing only the LSB in a byte have? What should I expect?. As you can see, I'm getting only "new" characters even when i shouldn't.
So I'm still a little unsure what you are trying to accomplish here but since you are trying to modify individual bits of a byte I would propose using the following data structure:
union bit_byte
{
struct{
unsigned bit0 : 1;
unsigned bit1 : 1;
unsigned bit2 : 1;
unsigned bit3 : 1;
unsigned bit4 : 1;
unsigned bit5 : 1;
unsigned bit6 : 1;
unsigned bit7 : 1;
} bits;
unsigned char all;
};
This will allow you to access each bit of your byte and still get your byte representation. Here some quick sample code:
bit_byte myValue;
myValue.bits.bit0 = 1; // Set the LSB
// Test the LSB
if(myValue.bits.bit0 == 1) {
myValue.bits.bit7 = 1;
}
printf("%i", myValue.all);
bitwise:
set bit => a |= 1 << x;
reset bit => a &= ~(1 << x);
bit check => a & (1 << x);
flip bit => a ^= (1 << x)
If you can not manage this you can always use std::bitset.
Helper macros:
#define SET_BIT(where, bit_number) ((where) |= 1 << (bit_number))
#define RESET_BIT(where, bit_number) ((where) &= ~(1 << (bit_number)))
#define FLIP_BIT(where, bit_number) ((where) ^= 1 << (bit_number))
#define GET_BIT_VALUE(where, bit_number) (((where) & (1 << (bit_number))) >> bit_number) //this will retun 0 or 1
Helper application to print bits:
#include <iostream>
#include <cstdint>
#define GET_BIT_VALUE(where, bit_number) (((where) & (1 << (bit_number))) >> bit_number)
template<typename T>
void print_bits(T const& value)
{
for(uint8_t bit_count = 0;
bit_count < (sizeof(T)<<3);
++bit_count)
{
std::cout << GET_BIT_VALUE(value, bit_count) << std::endl;
}
}
int main()
{
unsigned int f = 8;
print_bits(f);
}

Parsing a bit field parameter, how to "discard" bits in an unsigned long?

First of all, I want to know if this is possible: let's say I have an unsigned long which contains some abritrary unsigned shorts, which may or may not be in the number. For example:
unsigned short int id1 = 3456,
id2 = 30998;
unsigned long long bitfld = id1|id2;
Can the other 2 fields be assumed as 0? And is OR the right operation for this? After that let's say I pass bitfld as an argument:
void dostuff (unsigned long long bf)
{
//pseudo code
if( the first field exists in bf)
get first field;
if( the second field exists in bf)
get second field;
//etc...
}
I think I have to poll out the first 16 bits of the bitfield and check those, then recursively poll them, verify them and store them if they are greater than 0. But I'm not sure how to do this, bit shifting only shifts left or right, thus, it only divides or multiplies right?
sorry for the bump. Thanks all for your answers, but I ended up using a simpler and more efficient method, an internal structure. You see, I could have done this easily with a string, but my purpose was transparency to the user of the code, easy to program so to say.
I created an internal structure to hold my values and then a public method to create and return such structure, so it is easy to use and faster to parse (though it has the overhead of allocating in the stack a (albeit small) structure, which the bit field solution hasn't, but alas).
So thank you all for your answers.
short int is 2 bytes long, but long long is 8 bytes, so you have some kind of length mismatch;
You may have meant this:
unsigned long long bitfld = id1|(id2<<16);
you can check is there is a field occupied by ANDing it like:
void dostuff (unsigned long long bf)
{
//pseudo code
if(bf & 0xFFFF)
return bf & 0xFFFF;
if(bf & 0xFF00)
return (bf & 0xFFFF0000) >> 32;
//etc...
}
The bitwise OR operation is not what you want. The operation will merge existing bits with the new bits. You want an operation that replaces bits.
So first, you will need to clear out the bits using AND and NOT:
unsigned short int id1 = 3456,
id2 = 30998;
unsigned long long bitfld;
unsigned short int all_ones = ~0;
const unsigned int id2_position = 1;
const unsigned int bits_to_shift_left = id2_position * sizeof(unsigned short) * CHAR_BIT;
unsigned long long mask = ~(all_ones << bits_to_shift_left);
bitfld = bitfld & mask; // Erase all bits in id2 position
bitfld = bitfld | (id2 << bits_to_shift_left); // Put value into second position.
Unless lack of memory space is an issue, this kind of bit packing is not worth the development effort, validation time and extra execution time. Place the values into a "packed" buffer of unsigned char, then use the buffer with I/O.
You probably should review the bitshift operators and how they work. If you simply do:
id1 | id2, you basically mashed all the bits together. You would not be able to extract these values individually later. What you wanted to do is something like id1 | (id2 << 16) as pointed out by the user alemjerus.
Another way of accomplishing the same goal without bitshitting is to use a union:
struct s_btfld {
unsigned short int f1;
unsigned short int f2;
unsigned short int f3;
unsigned short int f4;
};
union u_btfld {
struct s_btfld fields;
unsigned long long value;
};
Now you can do:
unsigned short int id1 = 3456, id2 = 30998;
union u_btfld bitfld;
bitfld.fields.f1 = id1;
bitfld.fields.f2 = id2;
dostuff(bitfld.value);
And in dostuff, you can easily retrieve the fields by:
void dostuff(unsigned long long bf) {
union u_btfld a;
a.value = bf;
printf("id1 = %d\n", a.fields.f1);
printf("id2 = %d\n", a.fields.f2);
}
Assuming unsigned short is 2 bytes and an unsigned long is 4 bytes.
unsigned short id1 = 0x0d80; //3456 decimal
unsigned short id2 = 0x7916; //30998 decimal
unsigned long bitfld = ((id2<<16)|id1) //id2<<16 = 0x79160000, so bitfld = 0x79160d80
if ((bitfld & id1) == id1) {
//id1 is in lower 2 bytes of bitfld
}
if ((bitfld>>16) &id2) == id2) { //bitfld>>16 = 0x00007916
//id2 is in upper 2 bytes of bitfld
}
Does this help?
When dealing with bits it's easier to visually see what is happening if you work with hex values.