【问题标题】:Aligning bit pattern by most-significant bit按最高有效位对齐位模式
【发布时间】:2017-05-18 11:32:41
【问题描述】:

我想对两个数字进行异或如下:

11001110 和 110

但是,我需要像这样对齐位模式:

11001110
11000000

任何想法如何做到这一点?我想可能需要一些按位运算,但我怎么知道要移位多少位?

【问题讨论】:

  • 不,它们需要如上所示对齐。
  • 我怎么知道要移动多少位?这取决于输入值的位数。
  • 肯定将 110 移动 8 会产生错位。同样,我们如何知道最高位的位置?
  • @MartinRand 请向我们展示更多示例。第二个值的范围是多少(可能是 000 到 111)?
  • 投票结束因为不清楚,因为没有盲目猜测是不可能给出答案的。

标签: c bit xor


【解决方案1】:

这是一次尝试,假设我的要求正确:

int topbit(unsigned int x)
{
    for (int i = CHAR_BIT * sizeof x - 1; i >= 0; --i)
    {
        if (x & (1u << i))
            return i;
    }
    return -1;
}

unsigned int alignedxor(unsigned int a, unsigned int b)
{
    const int topa = topbit(a);
    const int topb = topbit(b);
    if (topa < 0)
        return b;
    if (topb < 0)
        return a;
    if (topa > topb)
        return a ^ (b << (topa - topb));
    return (a << (topb - topa)) ^ b;
}

int main(void) {
    printf("%x\n", alignedxor(0xce, 6));
    printf("%x\n", alignedxor(6, 0xce));
    return 0;
}

这会打印两次e,这似乎是正确的,但这就是我所做的所有测试。

是的,您可以更有效地获取最高 1 位的索引,但谁在乎呢?还用我丰富的想象力来处理极端情况(比如一个数为0)。

【讨论】:

    【解决方案2】:

    要知道在 Windows 上要移动多少位,您可以使用这个特定于 MS 的函数:_BitScanReverse 或者您可以实现自己的,类似于:

    int findFirstSetBit(uint32_t _n)
    {
        int idx = 31;
        for( ; idx >= 0; --idx){
            if(_n & (1 << idx) != 0){
                return idx;
            }
        }
        return -1;
    }
    

    【讨论】:

    • 对于 GCC 也有 __builtin_clz
    • 或者使用posix 2001 ffs。
    • 不应该idx = 32,所以我们从第31位开始?
    • 您的函数使用了保留名称!
    • @Olaf 那是哪个保留名称?如果您正在考虑_n,那么我一定不同意,因为只有在全局命名空间中才会保留这样的名称(在这种情况下不是这样)。至少根据语言标准。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-25
    • 2020-09-07
    • 1970-01-01
    • 1970-01-01
    • 2013-02-11
    • 1970-01-01
    • 2011-05-31
    相关资源
    最近更新 更多