在使用bit
时,是否有任何有效的算法允许将位index
插入位置uint16_t
?我已经尝试在index
之后逐位读取,将所有这些位存储到char
的数组中,在index
处更改位,增加index
,然后再次循环,从数组中获取位,但可能有更好的方法吗?所以我知道如何获取,设置,取消设置或切换特定位,但我认为可能有比逐位处理更好的算法。
uint16_t bit_insert(uint16_t word, int bit, int index);
bit_insert(0b0000111111111110, 1, 1); /* must return 0b0100011111111111 */
P.S。解决方案必须是纯ANSI兼容的C.我知道0b
前缀可能特定于gcc
,但我在这里使用它来使事情变得更加明显。
答案 0 :(得分:4)
使用按位运算符:
#define BIT_INSERT(word, bit, index) \
(((word) & (~(1U << (index)))) | ((bit) << (index)))
答案 1 :(得分:1)
#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。我还为_Bool
语句中的bit
参数提供了一些C99的return
行为:0为0,任何其他值为1.如果使用C99编译器,我建议将bit
的类型更改为_Bool
。然后,您可以直接将(!!bit)
替换为bit
。
我想说它可以进行优化,但这很可能会让它变得难以理解。
快乐的编码!
答案 2 :(得分:0)
如果您正在计算左侧的位
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);
可能有很多方法更有效,但这种方式很容易理解