tags:

views:

462

answers:

8

So if I have an integer that is 32 bits. The first 28 bits (from left) are to store the size of a memory chunk, the next two are 0s and the last two are:

  • to store the if it is the last node and then
  • to store if it is used or not (respectively).

What I am trying to do is to know how to turn the flag on and off on the isLast operation and the isUsed operation.

(If we consider only the last two integers (again, we start left) then 01 would be not last and is used for example, one more example is 11 is last and is used, 00 is not last and not used.)

I want to be able to turn the flags on and off in an easy way. I know I will need to use bit operations including & and | but I am not sure how.

Please ask me questions if you need more description of the problem.

+3  A: 
//turn on isUsed
data |= 1;
//turn off isUsed
data &= ~1;
//turn on notLast
data &= ~2;
//turn off notLast
data |= 2;
Andreas Brinck
Maybe add a "int const USED_FLAG 1" / "int const LAST_FLAG 2"?
Sebastian
and I think "data |= 2" means it is the last node, not the opposite
Sebastian
LnxPrgr3
Yeah he implemented notLast instead of isLast but that is ok :)
-1: [ http://codepad.org/w6dcXG4q ] xor doe **not** turn off a bit
pmg
XOR will switch the bit, not turn it off. Set with OR, unset with NOT AND, switch with XOR.
David Rodríguez - dribeas
frunsi
Andreas Brinck
pmg
@Andreas, a bit xored with 1 becomes 1 or 0 *based on its current value*. You really do need to and with the complement if you want the bit turned off no matter its current state.
paxdiablo
@paxdiablo Yes I know this, my original version was correct but I was a little quick to jump on the `^=` band wagon from the other posts, sorry
Andreas Brinck
+7  A: 

This is very simple:

/* Turn on bit 0 */
code = code | 1;

/* Turn off bit 0 */
code = code & ~1;

/* Turn on bit 1 */
code = code | 2;

/* Turn off bit 1 */
code = code & ~2;

See Bitwise operators in C, or Google for the appropriate terms. You can find this in any book or tutorial about C.

Jesper
+3  A: 

Turn the flag on:

register |= (1<<LAST_BIT);

Turn the flag off:

register &= ~(1<<LAST_BIT);

Another way is to use union bit-fields:

union
{
  uint32_t value;
  struct
  {
    unit32_t body:28;
    unit32_t reserved:2;
    unit32_t last_bit:1;
    unit32_t used_bit:1;
  } fields;
} MyResister;

MyResister.fields.last_bit = 1;
MyResister.fields.used_bit = 0;
kgiannakakis
I wouldn't recommend this, there's no guarantee that `body`, `reserved` etc will be packed in memory, in other words: `sizeof(MyRegister)` may or may not be `sizeof(uint32_t)`. See standard 9.6.1.
Andreas Brinck
Bit fields are definitely non-portable and compiler specific. However many compilers (especially for embedded processors) behave as expected. In such cases they are very handy.
kgiannakakis
+3  A: 

In general, counting the least significant bit as 0, to set bit N, you need to OR the original value with 1 << N.

Eg to set bit 1:

val |= (1 << 1);

To clear bit N, you need to AND the original value with the bit-wise inverse of 1 << N.

Eg to clear bit 1:

val &= ~(1 << 1);
Vicky
+1  A: 

http://www.pixelbeat.org/libs/bitops.h

pixelbeat
A: 
#include <assert.h>

unsigned int TurnOn( unsigned int i, unsigned int bit ) {
    assert( bit <= 31 );
    return i | (1 << bit);
}

unsigned int TurnOff( unsigned int i, unsigned int bit ) {
    assert( bit <= 31 );
    return i ^ (1 << bit);
}
anon
+1: Xor should be faster for turning off a bit than negation and logical and.
kgiannakakis
-1: xor does **not** turn off a bit
pmg
Pascal Cuoq
@prng How so? 1 ^ 1 = 0
anon
@Neil, xoring a bit with 1 will turn it on or off depending on its current state. But I see you've already corrected your answer :-)
paxdiablo
@pacdiablo No, I didn't "correct" my answer, I changed the composite assignment ops to the equivalent non-assignment op. And to me , turning a bit off indicates that it must previously have been on. Have you ever used a light switch?
anon
No, turning a bit off means making sure it's off, either by leaving it off or changing it to off. That way, you don't have to worry about the current state. With the xor solution you first have to check that it's on before turning it off.
paxdiablo
Check it out [ http://codepad.org/tHjXTOiO ]
pmg
@paxdiablo that is SETTING a bit. If I had called my function SetBit(), you would be entirely correct.
anon
We're going to have to agree to disagree there, Neil. In my opinion, setting a bit is forcing it to 1, clearing a bit is forcing it to 0. Those operations are the same to me as turning it on and off respectively, regardless of the current state. I've never in all my years seen a situation where you didn't want to force the change in that way. Otherwise to turn off a light (as you eloquently put it) that's already off would mean turning it *on* - that's a toggle operation, useful as well but not to be confused with turning something off. Still ,I don't feel strongly enough to vote down.
paxdiablo
In my code, whenever I change state, I know what the previous state was. Otherwise, I'm in trouble.
anon
Then why don't you use the xor for TurnOn as well? :-)
paxdiablo
@Neil If this is the case you only need one function (the one in `TurnOff`). As it is now there's an asymmetry between `TurnOn` and `TurnOff`, one unconditionally sets a bit and the other toggles it.
Andreas Brinck
@Andreas arguably true. However, use of a particularly named function can document intent un the code.
anon
Yes, it is inconsistent. Give this as an API to a fellow programmer, without the implementation, and it becomes a bug waiting to happen.
Secure
You may not always be able to know the previous state or control it. What if the data comes from an external source (like user input) or a different asychronous thread? In this case, TurnOff() will not do what it sounds like.
drhirsch
+2  A: 

This is begging for an interface, either with functions or macros, something like:

// Use unsigned ints (assuming that's your 32-bit type).

#define setLast(x)   (x) |=  2
#define clrLast(x)   (x) &= ~2
#define isLast(x)    ((x) &  2)

#define setUsed(x)   (x) |=  1
#define clrused(x)   (x) &= ~1
#define isUsed(x)    ((x) &  1)

You can also provide macros to extract the size portion and create the whole integer:

#define getSize(x) ((x) >> 4)
#define create (sz,last,used) \
    (((sz) & 0x0fffffff) << 4) | \
    (((last) & 1) << 1) | \
    (((used) & 1))

You'll find your code becomes a lot more readable if you provide the "functions" to do the work and give them sensible names like the above. Otherwise your code is peppered with bit manipulation instructions that are harder to understand.

Just keep in mind the normal rules for macros, things like not passing in things like x++ if your macros use it more than once (which isn't actually the case here). If you want to be ultra-safe, you can do them as functions.

Equivalent functions would be:

unsigned int setLast (unsigned int *x) { *x |=  2; return *x; }
unsigned int clrLast (unsigned int *x) { *x &= ~2; return *x; }
unsigned int isLast  (unsigned int  x) { return x & 2; }

unsigned int setUsed (unsigned int *x) { *x |=  1; return *x; }
unsigned int clrUsed (unsigned int *x) { *x &= ~1; return *x; }
unsigned int isUsed  (unsigned int  x) { return x & 1; }

unsigned int getSize (insigned int  x) { return x >> 4; }
unsigned int create  (unsigned int sz, unsigned int last, unsigned int used) {
    unsigned int ret =
        ((sz & 0x0fffffff) << 4) |
        ((last & 1) << 1) |
        ((used & 1));
    return ret;
}
paxdiablo
Even more readable if you actually make them functions. Also, in each of your macros, x should be (x), to avoid unexpected precedence issues.
anon
A: 

I would throw in a BIT(x) macro just to make the source code more clear:

#define BIT(n) (0x1U << (n))

Which would result in:

#define LAST_SET(x) ((x) |= BIT(1))
#define LAST_CLR(x)  ((x) &= ~BIT(1))

Also, as previously noted, always put the parameter in parenthesis.

(OT) Edit: Changed name of macro as I do not like having the verb first. First of all a function like getWhatever is for code where you can group the function in a class. In C, IMHO, you should put the "component" name first such as, timeGet() et c

(OT2) Also if it's a register macrofication like this is nice which would result in better portability:

#define MY_REG_RD() (MY_REG)
#define MY_REG_WR(x) (MY_REG = (x))
#define MY_REG_SET(x) (MY_REG |= (x))
#define MY_REG_CLR(x) (MY_REG &= ~(x))
#define MY_REG_DIS BIT(10)
#define MY_REG_EN BIT(4)

Then you could do:

MY_REG_SET(MY_REG_EN);
Henrik
(OT) I mostly agree with you. What I say is to name variables in big endian format: the most important word first. Compare `timeGet()`, `timeSet()`, `timeAdvance()`, ... where `time` is the most important word ... with `fixTime()`, `fixLength()`, `fixWeight()`, ... where "fixing" is more important :)
pmg
@Henrik, I think your LAST_CLR should use ~BIT(1), yes?
paxdiablo
You're absolutely right, fixed!
Henrik
mostly good, except for the fact that the int variable is now hardcoded as `MY_REG`, or do you expect to def/undef it everytime? It is now actually more obscure what memory these macros affect.
catchmeifyoutry
catchmeifyoutry,I do not mean that this should be used for common memory variables. This is for registers in an ASIC. I should have made that more clear, sorry.
Henrik