[使用C0]时是否有任何有效的算法可以将bit
位插入到index
位置?我尝试逐位读取uint16_t
之后的内容,将所有这些位存储到index
的数组中,更改char
的位,增加index
,然后再次循环,从数组中插入位,但是可以有更好的方法吗?因此,我知道如何获取,设置,取消设置或切换特定位,但是我想可能有比逐位处理更好的算法。
index
P.S。该解决方案必须使用与ANSI兼容的纯C语言。我知道uint16_t bit_insert(uint16_t word, int bit, int index);
bit_insert(0b0000111111111110, 1, 1); /* must return 0b0100011111111111 */
前缀可能特定于0b
,但是在这里我用它来使事情变得更明显。
使用按位运算符:
gcc
#define BIT_INSERT(word, bit, index) \
(((word) & (~(1U << (index)))) | ((bit) << (index)))
位通常从最低有效位(lsb)所在的右侧到最高有效位(msb)所在的左侧进行计数。我通过创建两个函数允许从任一侧插入。根据问题,期望的是#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));
}
。
[这两个功能都执行完整性检查,如果bit_insert_msb
的值太大,则将errno
设置为ERANGE
并返回0。我还为idx
语句中的_Bool
参数提供了C99的bit
行为:0为0,任何其他值为1。如果您使用C99编译器,建议您更改return
的输入bit
。然后,您可以将_Bool
直接替换为(!!bit)
。
我很乐意说可以对其进行优化,但这很可能会使它难以理解。
快乐编码!
如果您从左数起位
bit
可能有许多方法更有效,但这种方法很容易理解