2

Let's say I have some 32 bit integer:

000001010100010000100010001001 1 0

(The penultimate bit is bold/italic)

So if I shift it by 2 to the right I get:

00000001010100010000100010001001

Now the penultimate bit is lost. I thought of storing the original value and then using || (logical OR), but that would only work if the penultimate bit is set to 1. What if it's 0?

ulak blade
  • 2,515
  • 5
  • 37
  • 81
  • 1
    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) – tgmath Aug 21 '14 at 16:21
  • I don't understand the question at all. Obviously, if you shift a value, all of the bits you shift out are lost; that's the definition of shifting. So what are you trying to do? If you want to save the next to the last bit, you need to save it before shifting (or save the last bit after having shifted `n-1`). – James Kanze Aug 21 '14 at 16:47

3 Answers3

9

You'd want bitwise, not logical or; and to preserve the value, you'd need to clear the bit in the new value before inserting the one from the old value:

uint32_t const shift = 2; // number of bits to shift by
uint32_t const mask = (1 << 1); // set of bits to preserve

uint32_t bit_to_save = value & mask;
value >>= shift;
value &= ~mask;
value |= bit_to_save;

or, if you like brevity:

value = ((value >> shift) & ~mask) | (value & mask);
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • But how on earth did his question make you think that this is what he was trying to do? – James Kanze Aug 21 '14 at 16:48
  • 2
    @JamesKanze: Basic reading comprehension. This shifts the bits without changing one of them, exactly as the question describes. – Mike Seymour Aug 21 '14 at 16:51
  • Well, I still can't figure it out from what he wrote. – James Kanze Aug 21 '14 at 17:18
  • And you might add something concerning the relationship between `mask` and `shift`. – James Kanze Aug 21 '14 at 17:20
  • @JamesKanze: There's no relationship. One's the number of bits to shift by; the other's the mask of bits to preserve. But I'll add comments in case anyone else can't guess the meaning from the names. – Mike Seymour Aug 21 '14 at 20:10
  • Ah, yes. I hadn't realized that in this case, the two really are independent. (I often have a mask and a shift count which are related.) – James Kanze Aug 22 '14 at 08:11
4

Use bitwise operations:

(x>>2) & ~2 | (x&2)

x>>2 shifts right by 2.

& ~2 sets the penultimate bit to 0

| (x&2) 'grafts' in the penultimate bit from the original number.

jtlim
  • 3,861
  • 1
  • 16
  • 14
0
int x;//whatever
int penultimate_shift=(x&0x2)|((x>>2)&~0x2);
IdeaHat
  • 7,641
  • 1
  • 22
  • 53
  • Would you be able to provide a bit more detail as to what is going on here? – NT3RP Aug 21 '14 at 17:01
  • x&0x2 selects the "panultimate" bit, x>>2 is the bit shift, the result of that is reset, and then the or sets it to the panultimate bit – IdeaHat Aug 21 '14 at 17:32