繁体   English   中英

将位插入 uint16_t

[英]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

这两个函数都执行健全性检查,将errnoERANGE ,如果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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM