0

I wonder if there is a nice way to get the shift that is required out of a bitmask applied to a variable without the need to define it.

Simple Example:

#define MASK  0xf0
#define SHIFT 4

uint8_t var = 0x20;
uint8_t wanted = (var & MASK) >> SHIFT;

How can I avoid using the SHIFT define but still get the same result?

user3482407
  • 319
  • 3
  • 18
  • 1
    Using `wanted = (var & MASK) >> 4;` of course. There is nothing magical about `#define`s. – Jongware Oct 19 '18 at 10:22
  • Why is there an equal to sign in `#define`...! – Ruks Oct 19 '18 at 10:23
  • @usr2564301: sure, but I want shift to be "generated" from the value in MASK – user3482407 Oct 19 '18 at 10:23
  • Unsure what you are asking. Do you want to find out `SHIFT` so that `(var & MASK) >> n == wanted` holds for some `wanted`? – Acorn Oct 19 '18 at 10:24
  • @Ruks Edited, thx – user3482407 Oct 19 '18 at 10:24
  • Could you clarify what you are trying to ask... – Ruks Oct 19 '18 at 10:25
  • @user3482407 Ah, so you want to find out `SHIFT` given only `MASK`, assuming `MASK` is a proper "mask". That means you are trying to find the lowest set bit in `MASK`, right? – Acorn Oct 19 '18 at 10:25
  • @Acorn Exactly! – user3482407 Oct 19 '18 at 10:26
  • @user3482407 Then see [Position of least significant bit that is set](https://stackoverflow.com/questions/757059/position-of-least-significant-bit-that-is-set) – Acorn Oct 19 '18 at 10:26
  • @user3482407 Then you have to know the value of `wanted` beforehand... and `>>=` over all possible combinations from 1 to n checking if they are equal your number along with the way... – Ruks Oct 19 '18 at 10:26
  • @Acorn Thanks, but this is not really what I am looking for, I would prefer the additional defines instead of the whole function – user3482407 Oct 19 '18 at 10:30
  • @Ruks Can you clearify that? If I understand corret, this would mean that you shift through the whole variable in a loop and compare for "wanted", but what happens when var would be 0x02? – user3482407 Oct 19 '18 at 10:33
  • @user3482407 Oh, my mistake, I meant *0 to n*... – Ruks Oct 19 '18 at 10:35
  • 2
    gcc was not tagged. But for it: `(var & MASK) >> __builtin_ctz(MASK)` – SKi Oct 19 '18 at 10:37
  • Any reason why you can't do `#define GET_STUFF(x) ((x >> 4) & 0xFF)`? – Lundin Oct 19 '18 at 10:41
  • @user3482407 Not sure what you mean: that question is precisely what you are looking for. There are many answers, and you can pick the solution that you prefer. – Acorn Oct 19 '18 at 10:50
  • @SKi: This is awesome, exactly what I was looking for. Thanks! – user3482407 Oct 19 '18 at 10:54
  • 1
    You could do `uint8_t wanted = WANTED(var, mask);`, where `#define WANTED(var, mask) (((var) & (mask)) / ((mask) & ~((mask) - 1)))`. – Ian Abbott Oct 19 '18 at 11:12

0 Answers0