9

What is a optimal way to replace the Least Significant Bit of a byte, with a provided bit?

I know how to do checking and comparing last bit (using for example posix ffs() function), but I want to know if there are solutions with better performance, without checking if replacing bit is 0 or 1.

The example is written in python as pseudocode, but I will implement the working algorithm in C:

>>> bin(0b1)             # bit is  '0b1'
>>> bin(128)             # byte is '0b10000000'
>>> bin(129)             # byte is '0b10000001'

>>> bin(128 OPERATOR 0b1)       # Replace LSB with 1
'0b10000001'
>>> bin(128 OPERATOR 0b0)       # Keep LSB at 0
'0b10000000'

>>> bin(129 OPERATOR 0b1)       # Keep LSB at 1
'0b10000001'
>>> bin(129 OPERATOR 0b0)       # Replace LSB with 0
'0b10000000'

Obviously operator can be a set of operations, but I'm looking for the optimal (fastest) method.

Emilio
  • 3,901
  • 11
  • 44
  • 50

2 Answers2

21

n & ~1 replaces the least significant bit of n with zero; n | 1, with one.

To replace the LSB with b, where b can be either 0 or 1, you can use (n & ~1) | b.

To replace the k-th bit with b (where k=0 stands for the LSB): (n & ~(1 << k)) | (b << k).

NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • I have always to check before if my replacing bit is 0 or 1. There is an 'universal' operator? – Emilio May 19 '11 at 13:34
  • Another help, if you can. If i want to set a given bit in a particular byte position, i can set 1 using `x = x | pos` or `x = x & ~pos` to set 0. Can i merge this two function in a single logic statement that works with 1 and 0? Thank you. – Emilio May 19 '11 at 23:33
  • @Emilio: for that, you just have to left-shift `b`. See the updated answer. – NPE May 20 '11 at 06:25
0

You also might want to check if you are on big endian or little endian architecture. In big endian machines the least significant byte is at the highest address.

In Python you can check endian-ness by

sys.byteorder

In C you need to check endian-ness on your own, hack using unions is easy to do.

Xolve
  • 22,298
  • 21
  • 77
  • 125