[英]Insert bit into uint16_t
是否有任何有效的算法允许在使用uint16_t
时插入bit
来定位index
? 我试过在index
之后逐位读取,将所有这些位存储到char
数组中,更改index
位,增加index
,然后再次循环,从数组中插入位,但有没有更好的方法? 所以我知道如何获取、设置、取消设置或切换特定位,但我认为可能有比逐位处理更好的算法。
uint16_t bit_insert(uint16_t word, int bit, int index);
bit_insert(0b0000111111111110, 1, 1); /* must return 0b0100011111111111 */
PS 解决方案必须是纯 ANSI 兼容的 C。我知道0b
前缀可能特定于gcc
,但我在这里使用它以使事情更加明显。
使用按位运算符:
#define BIT_INSERT(word, bit, index) \
(((word) & (~(1U << (index)))) | ((bit) << (index)))
#include <errno.h>
#include <stdint.h>
/* Insert a bit `idx' positions from the right (lsb). */
uint16_t
bit_insert_lsb(uint16_t n, int bit, int idx)
{
uint16_t lower;
if (idx > 15) {
errno = ERANGE;
return 0U;
}
/* Get bits 0 to `idx' inclusive. */
lower = n & ((1U << (idx + 1)) - 1);
return ((n & ~lower) | ((!!bit) << idx) | (lower >> 1));
}
/* Insert a bit `idx' positions from the left (msb). */
uint16_t
bit_insert_msb(uint16_t n, int bit, int idx)
{
uint16_t lower;
if (idx > 15) {
errno = ERANGE;
return 0U;
}
/* Get bits 0 to `16 - idx' inclusive. */
lower = n & ((1U << (15 - idx + 1)) - 1);
return ((n & ~lower) | ((!!bit) << (15 - idx)) | (lower >> 1));
}
位通常从右侧(最低有效位 (lsb) 所在的位置)到左侧(最高有效位 (msb) 所在的位置)进行计数。 我通过创建两个函数允许从任何一侧插入。 根据问题,预期的是bit_insert_msb
。
这两个函数都执行健全性检查,将errno
为ERANGE
,如果idx
的值太大,则返回 0。 我还在return
语句中为bit
参数提供了 C99 的一些_Bool
行为:0 是 0,任何其他值都是 1。如果您使用 C99 编译器,我建议将bit
的类型更改为_Bool
。 然后你可以直接用bit
替换(!!bit)
。
我很想说它可以被优化,但这很可能会使它变得不那么容易理解。
快乐编码!
如果你从左边数位
mask = (1 << (16 - index + 1)) - 1; // all 1s from bit "index" to LSB
// MSB of word (from left to index) | insert bit at index | LSB of word from (index-1)
word = (word & ~mask) | (bit << (16 - index)) | ((word & mask) >> 1);
可能有很多方法更有效,但这种方式很容易理解
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.