Заменить младший значащий бит побитовыми операциями

Каков оптимальный способ замены наименее значимого бита байта предоставленным битом?

Я знаю, как проверять и сравнивать последний бит (используя, например, функцию posix ffs()), но я хочу знать, есть ли решения с лучшей производительностью, не проверяя, является ли замена бита 0 или 1.

Пример написан на питоне в виде псевдокода, но я реализую рабочий алгоритм на 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'

Очевидно, оператор может быть набором операций, но я ищу оптимальный (самый быстрый) метод.


person Emilio    schedule 19.05.2011    source источник


Ответы (2)


n & ~1 заменяет младший значащий бит n нулем; n | 1, с одним.

Чтобы заменить LSB на b, где b может быть либо 0, либо 1, вы можете использовать (n & ~1) | b.

Чтобы заменить k-й бит на b (где k=0 обозначает младший бит): (n & ~(1 << k)) | (b << k).

person NPE    schedule 19.05.2011
comment
Я всегда должен заранее проверять, равен ли мой замещающий бит 0 или 1. Существует ли «универсальный» оператор? - person Emilio; 19.05.2011
comment
Еще помогите, если можете. Если я хочу установить данный бит в определенной позиции байта, я могу установить 1, используя x = x | pos или x = x & ~pos, чтобы установить 0. Могу ли я объединить эти две функции в один логический оператор, который работает с 1 и 0? Спасибо. - person Emilio; 20.05.2011
comment
@Emilio: для этого вам просто нужно сдвинуть влево b. Смотрите обновленный ответ. - person NPE; 20.05.2011

Вы также можете проверить, используете ли вы архитектуру с прямым порядком байтов или прямым порядком байтов. В машинах с обратным порядком байтов младший байт находится по старшему адресу.

В Python вы можете проверить порядок байтов с помощью

sys.byteorder

В C вам нужно проверить порядок следования байтов самостоятельно, взломать с помощью союзов легко.

person Xolve    schedule 19.05.2011
comment
Я не понимаю, какое отношение порядок байтов имеет к этому вопросу. Решение @aix будет работать независимо от порядка байтов. - person Simon Nickerson; 19.05.2011
comment
@ Саймон, да, ты прав. 1 - это int, и он также будет следовать тому же порядку байтов. - person Xolve; 19.05.2011