将位插入uint16_t

问题描述 投票:1回答:3

[使用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,但是在这里我用它来使事情变得更明显。

c bit-manipulation bit bit-shift
3个回答
4
投票

使用按位运算符:

gcc

1
投票
#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)

我很乐意说可以对其进行优化,但这很可能会使它难以理解。

快乐编码!


0
投票

如果您从左数起位

bit

可能有许多方法更有效,但这种方法很容易理解

© www.soinside.com 2019 - 2024. All rights reserved.