【问题标题】:Optimize Boolean Mask Assignment优化布尔掩码分配
【发布时间】:2016-10-12 04:13:23
【问题描述】:

这个问题本质上类似于:Is -!(condition) a correct way to obtain a full-bitvector from a boolean (mask-boolean)?

作为硬件解决方案的一部分,我想实现条件检查和随后将所有“1”或“0”位分配给 32 位整数。

我的代码是:value & ~(!(x & y) - 1)。如果 x 和 y 的位之间有一些重叠,则 value 设置为 0,否则 value 将保持不变。

我的问题是如何优化此语句以减少涉及的运算符数量。这是否可能仅使用一元和二进制整数运算! ~ & ^ | + - * / % << >>

这是我的代码供参考,它将 x 的低位 n 位重复到字长:

int bitRepeat(int x, int n) {
/* Mask desired bits, shift and OR by larger intervals each time, return repeated pattern */    

/* Check for n = 32, set a to all 1's if n != 32 */ 
int nMax = ~(!(n & 31)-1);  

/* Mask low-order n bits */
int maskBits = ~(~0 << n) & x;  

/* Initialize shift factors */  
int n2 = n * 2; 
int n4 = n * 4; 
int n8 = n * 8; 
int n16 = n * 16;

/* Shift and OR masked bits by intervals n * x {x: 1,2,4,8,16}, check for overflow at each step */  
int overFlowMask = ~0 << 5;
maskBits = maskBits | maskBits << n;
maskBits = maskBits | ((maskBits << (n2)) & ~(!((n2) & overFlowMask) - 1));
maskBits = maskBits | ((maskBits << (n4)) & ~(!((n4) & overFlowMask) - 1));
maskBits = maskBits | ((maskBits << (n8)) & ~(!((n8) & overFlowMask) - 1));
maskBits = maskBits | ((maskBits << (n16)) & ~(!((n16) & overFlowMask) - 1));

return (maskBits & ~nMax) | (x & nMax);
}

以某种能力实现unsigned 数据会有帮助吗?

【问题讨论】:

    标签: c bit-manipulation bitwise-operators boolean-logic


    【解决方案1】:

    你可以更容易地做到这一点(我们想用一个位模式的 n 次重复填充一个整数)。

    unsigned int bitRepeat(unsigned int x, int n)
    {
       unsigned int answer = 0;
    
       while(x)
       {
         answer |= x;
         x <<= n;
       }
    
       return answer;
    }
    

    您需要使用无符号整数,因为移出有符号整数的 MSB 可能会产生不可预知的后果。 (因为编译器可能 优化到 x *= poweroftwo,并设置算术溢出陷阱)。

    由于您不能使用循环,因此变得有点困难。正如你 观察到,如果整数是 32 位,那么最坏的情况是我们将 缓冲五次。

    所以

    int bitRepeat(int x, int n)
    {
       unsigned int rack = x;
    
       rack = (rack << n) | rack;
       n *= 2;
       rack = (rack << n) | rack;
       n *= 2;
       rack = (rack << n) | rack;
       n *= 2; 
       rack = (rack << n) | rack;
       n *= 2;
       rack = (rack << n) | rack;
    
       return rack;
    }
    

    不幸的是,如果轮班发生,这在技术上是未定义的行为 大于整数的大小。您的编译器可能会接受它。但是没有条件就很难压制。

    【讨论】:

    • 谢谢。不幸的是,我无法更改 int bitRepeat(int x, int n) 或使用循环/条件。将x 存储在unsigned 容器中会有帮助吗?
    猜你喜欢
    • 1970-01-01
    • 2013-02-01
    • 2021-12-31
    • 1970-01-01
    • 2017-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多