Bitmask - Left shift overflow [duplicate] - c

This question already has answers here:
Algorithm to generate bit mask
(9 answers)
Closed 4 years ago.
Problem:
I want to generate a Bit mask (uint32_t) based on a given length.
Following result should be achieved:
BIT_MASK(3) = 0x00..0111
BIT_MASK(32) = 0x111..111
The code given below is working for every length smaller than 32. If the length is 32, the left shift count is larger than the type width (overflow).
#define BIT(n) ( 1<<(n) )
#define BIT_MASK(len) ( BIT(len)-1 )
uint32_t length;
uint32_t mask = BIT_MASK(length);
Question:
Is there any other efficient macro solution to generate a Bit mask, which is not including an additional if/else or typecast to avoid that error.

This is pretty much it, but you need to change the literal 1 to 1UL. Otherwise you are restricted to the range of int, which is likely 31 bits instead of 32.
#define BIT_MASK32(n) ( (1UL<<(n)) - 1UL )
Where n must be in the range of 0 to 31 to fit a uint32_t. To safe guard against overflow, you could make it (n)%32, though that will make the macro slower if n is a run-time value rather than an integer constant.

Related

Zero specific bit without bitmask? [duplicate]

This question already has answers here:
How do I set, clear, and toggle a single bit?
(27 answers)
Closed 9 months ago.
I'd like to set a specific bit to 0 but without using a bitmask because I'm using enums and if the enum values change, enum fields get moved around then the bitmask would no longer be valid.
I can toggle a bit on, using a temporary variable then OR it with the already existing bitfield
#include <assert.h>
enum EState{
k_EStateNone,// bit 1 - 1
k_EStateFoo,// bit 2 - 10
k_EStateBar// bit 3 - 100
};
uint64_t togglebiton(uint64_t state,EState ebit){
uint64_t temp = 1<<ebit;
state|=temp;
return state;
}
int main(){
uint64_t state = 0;
state = togglebiton(state, k_EStateBar);
state = togglebiton(state, k_EStateFoo);
//foo bar = 110 == 6
assert(state == 6);
return 0;
}
But I'm unsure how to go about flipping the bit off, because I can't AND the whole thing with 0..
To flip a bit off, first shift the bit to the desired location, then use a bitwise NOT to invert all bits so that all but the target bit is set, then do a bitwise AND.
uint64_t togglebitoff(uint64_t state,EState ebit){
uint64_t temp = 1ULL<<ebit;
state&=~temp;
return state;
}
Also make sure that the constant you're shifting is of the correct type so that you don't shift into the sign bit of a signed type or more than the bit width of the type in question.

How to analyze bytes of a variable's value in C

is it possible to divide for example an integer in n bits?
For example, since an int variable has a size of 32 bits (4 bytes) is it possible to divide the number in 4 "pieces" of 8 bits and put them in 4 other variables that have a size of 8 bits?
I solved using unsigned char *pointer pointing to the variable that I want to analyze bytes, something like this:
int x = 10;
unsigned char *p = (unsigned char *) &x;
//Since my cpu is little endian I'll print bytes from the end
for(int i = sizeof(int) - 1; i >= 0; i--)
//print hexadecimal bytes
printf("%.2x ", p[i]);
Yes, of course it is. But generally we just use bit operations directly on the bits (called bitops) using bitwise operators defined for all discrete integer types.
For instance, if you need to test the 5th least significant bit you can use x &= 1 << 4 to have x just to have the 5th bit set, and all others set to zero. Then you can use if (x) to test if it has been set; C doesn't use a boolean type but assumes that zero is false and any other value means true. If you store 1 << 4 into a constant then you have created a "(bit) mask" for that particular bit.
If you need a value 0 or 1 then you can use a shift the other way and use x = (x >> 4) & 1. This is all covered in most C books, so I'd implore you to read about these bit operations there.
There are many Q/A's here how to split integers into bytes, see e.g. here. In principle you can store those in a char, but if you may require integer operations then you can also split the int into multiple values. One problem with that is that an int is just defined to at least store values from -32768 to 32767. That means that the number of bytes in an int can be 2 bytes or more.
In principle it is also possible to use bit fields but I'd be hesitant to use those. With an int you will at least know that the bits will be stored in the least significant bits.

Most elegant way of turning bits on and off [duplicate]

This question already has answers here:
How do I set, clear, and toggle a single bit?
(27 answers)
Closed 3 years ago.
I've got a register which can either be 0x02 or 0x01 (0010 or 0001). What is the most elegant way of setting the bits in a single operation? E.g. if the register is currently 0x02, I need to turn off bit 2 and turn on bit 1.
Many thanks
x ^= 3 changes 1 to 2 and changes 2 to 1. ^ performs an exclusive or (XOR) operation.
The most elegant way is to define a structure that uses bit fields. Sadly this is rarely appropriate when dealing with hardware registers (e.g. order of bits in a bit-field isn't well defined, etc).
Without bitfields; use "and with compliment" (e.g. x = x & ~ 2; or x &= ~2;) to clear bits and "or" (e.g. x = x | 1; or x |= 1;) to set bits.
If you know the previous value you can optimize further. For example, if you know the previous value is 0x02 then you can just set a new value (e.g. x = 0x01; // It was 0x02 or maybe x = (0x02 & ~2) | 1; so compiler will work out the constant for you but the source code still reflects how the constant was determined).
Note that it's not possible to do it in a single operation unless you do know something about the previous value. For example, if you know that the previous value will have bit 0 clear and bit 1 set but don't know anything about the other bits (and need to preserve the other bits), then you can decrement (x--; // Clear bit 2, set bit 1) or use exclusive OR.

How can I assign bit by bit to an integer in C? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do you set, clear and toggle a single bit in C?
I want to create an assembler , so I need to assign 32 bits bit by bit or field by field to create 32 bit opcode from assembly ... how can I do this in C ? how can I assign bits in integer ? can this be done ?
You can declare these two macros to help you:
#define Set_Bit(IntValue, BitNumber) IntValue = IntValue | (1<<BitNumber)
#define Clr_Bit(IntValue, BitNumber) IntValue = IntValue & (~((1) << (BitNumber))))
Some questions have discussed these before:
Macros to set and clear bits

Get single bytes from a word [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to get the value of individual bytes of a variable?
How can I get single bytes from a word (for example an unsigned int in C) without using bit-wise operations (that is using arithmetic operations?)
I don't know why, but this formula (C-Like) for an x number doesn't seem to work:
floor(x / pow(R, i)) % R
where R is the radix with which the number is represented, and i is used to indicate the i-th byte to obtain.
If you really need to avoid bitwise operations, you can cheat alternatively (beware if you're using a little or big endian machine!):
char *int_16_storage;
uint16_t the_word = 0xabcd;
int_16_storage = &the_word;
uint8_t low_byte = int_16_storage[0];
uint8_t high_byte = int_16_storage[1];

Resources