1

Suppose we have a byte B and a mask M such that one of the bits in the mask is either 1 or 0 and the others are 0, (suppose we know which bit that is, it can be any bit but for simplicity it's the LSB). We want that the same bit in B will have the same value as that bit from M.

For example if B=1111, M=0000 then we want to have after the operation B=1110, but if M was M=0001 then B would have been B=1111.

I'm basically asking how to implement the boolean function generated from this truth table:

old new result
0   0   0
0   1   1
1   0   0
1   1   1

So result would be:

a=old, b= new
result=a'b+ab

Doing B = ~B&M | B&M; in C doesn't seem to work...

I probably can do it with conditionals but there's got to be a way to it without them.

Another example: If we care about the second bit, and if B=0001, M=0010 then the result of the operation would be 0011. But if M was M=0000 then the result of the operation was 0001.

I know how to set clear and toggle a bit, this is not what I'm asking.

shinzou
  • 5,850
  • 10
  • 60
  • 124
  • 4
    I'm confused, based on your truth table, `f` is identical to `new` – kmdreko May 02 '16 at 20:49
  • I think it's a coincidence that they're identical. @vu1p3n0x Let's call it `result` instead of `f`. – shinzou May 02 '16 at 20:51
  • 1
    @kuhaku Give better examples or a concise algorithm then please. – πάντα ῥεῖ May 02 '16 at 20:52
  • 3
    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) – 19greg96 May 02 '16 at 20:53
  • I'm also confused by the example, if `input = 1111` and `mask = 0000` how is `output = 1110` after the operation? In my book `input = 1111` with `mask = 0000` should be `output = 0000`, and for example `input = 1101` with `mask = 0111` has `output = 0101`. Just use the bit-wise & operator. – 3limin4t0r May 02 '16 at 20:55
  • @πάνταῥεῖ ok I'll write more examples. – shinzou May 02 '16 at 20:55
  • @JohanWentholt Only one of the bits in the mask is to be considered, the others (which will be 0) should be ignored. – Ingo Bürk May 02 '16 at 20:55
  • `~B&M | B&M` is a funny way to write `M` – harold May 02 '16 at 21:11

5 Answers5

3

You need to specify the offset to the bit you care about (e.g. index):

char AssignBit(unsigned char byte, unsigned char mask, int index)
{
    unsigned char cleared = byte & ~(1 << index);
    unsigned char assigned = cleared | mask & (1 << index);
    return assigned;

    // or simply:
    return byte & ~(1 << index) | mask & (1 << index);

    // if it is guaranteed that at most one bit is set in mask, this also works:
    return byte & ~(1 << index) | mask;
}
MooseBoys
  • 6,641
  • 1
  • 19
  • 43
2

If I undestand correctly, you want to set a single bit from B to the value of that bit in M, and you don't care what the previous value in B was. M is not really a mask in this case; your mask is given by the bit number. So you'd do something like

unsigned mask = (1<<BITNUM);
unsigned result = (~mask & B) | (mask & M)

where BITNUM = 0 if it's the LSB.

thegreatemu
  • 495
  • 2
  • 11
1

It can't be implemented as a boolean function, as the operators you want to use are bit-wise, and so the operands are multi-bit. But you can incorporate some bit-shifts to accommodate that:

#define BIT_NUMBER   3  // For example

B &= ~(1 << BIT_NUMBER); // Zero out the bit
B |= M << BIT_NUMBER; // Set to M's bit value
Eugene Sh.
  • 17,802
  • 8
  • 40
  • 61
1

For example if B=1111, M=0000 then we want to have after the operation B=1110

The problem is that you haven't specified which bit in M is significant, and there's no way to determine the significant bit from the value of M.


You actually need three quantities, the byte B, the value V (which you're calling M), and a mask M (which is missing from your question).

Here's the code that combines the three:

result = (B & ~M) | (V & M);
user3386109
  • 34,287
  • 7
  • 49
  • 68
-1

How to change the nth bit to x:

number ^= (-x ^ number) & (1 << n);

(Taken from https://stackoverflow.com/a/47990/6149078)

Community
  • 1
  • 1
DarthRubik
  • 3,927
  • 1
  • 18
  • 54