0

I'm trying to drop (meaning zero the bit) the LSB from an address. The below piece of code which I wrote doesnt seem to do the thing I intended to do.

#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
struct node
{
    unsigned long key;
    struct node* child[2];
};
int main()
{
    struct node* node = (struct node*) malloc(sizeof(struct node));
    printf("%x\n",node);
    node = (struct node*)((uintptr_t) node >> 1UL);
    printf("%x\n",node);
}
arunmoezhi
  • 3,082
  • 6
  • 35
  • 54
  • And what _did_ you intend to do? – mafso Jul 30 '14 at 17:04
  • 3
    You need to include in your question the output of the above code, why you feel that it is incorrect, and what the output you would like for it to be. – Bill Lynch Jul 30 '14 at 17:08
  • It's not clear from your question if your intent is to zero the LSB or shift by 1, either of which could be called "dropping". Please clarify your question. – amo Jul 30 '14 at 17:15
  • possible duplicate of [How do you set, clear and toggle a single bit in C/C++?](http://stackoverflow.com/questions/47981/how-do-you-set-clear-and-toggle-a-single-bit-in-c-c) – amo Jul 30 '14 at 17:26

3 Answers3

3

If you want to clear the least significant bit, you can use:

(struct node*)((uintptr_t) node & (UINTPTR_MAX << 1))

but don't assign the result to node or you'll have a memory leak.

ouah
  • 142,963
  • 15
  • 272
  • 331
1

If you want to use the shift operator (as indicated in your comment on ouah's answer), you can use:

(struct node*)(((uintptr_t)node >> 1) << 1)
Jashaszun
  • 9,207
  • 3
  • 29
  • 57
1

If your intent is to zero the low order bit of a value you would use an expression like:

x = z & ~1; // assuming x, y, and 1 are of the same bit width

This complements 1, turning it into something like 0b111111...1110 and performs a bitwise AND with the value z. The effect is the lowest bit is set to 0 while all others retain their values.

The expression you used, node >> 1UL, performs a shift -- that is, the bit in position 31 is moved to position 30, 30 to 29, ..., and 1 to 0, and the lowest order bit is discarded. It is usually equivalent to an integer division by 2. If this is what you intended, you should have gotten it.

Jashaszun
  • 9,207
  • 3
  • 29
  • 57
  • Note that when you say `the bit in position 31 is moved to position 30`, that may not be the first bit moved (`1UL` does not need to be 32 bits). – Jashaszun Jul 30 '14 at 17:24
  • 1
    Also note that `~1` is equivalent to `-2`, and that both should be casted to the correct size. – Jashaszun Jul 30 '14 at 17:26