【问题标题】:how to guard against bit overflow in C using only bitwise operators如何仅使用位运算符来防止 C 中的位溢出
【发布时间】:2013-09-24 02:06:36
【问题描述】:

我必须重写一个方法来判断 x 是否小于或等于 y,只使用按位运算符而不使用条件语句。到目前为止我有这个:

int isLessOrEqual(int x, int y)
{
    int a = x + (~y) + 1;
    return ((a&0x80000000) >> 31);
}

但我不知道如何防止溢出?谁能伸出援助之手?

【问题讨论】:

  • (不相关)请注意,如果值为负数,则右移有符号整数会导致实现定义的行为。
  • 在此分配中,+ 是否被视为位运算符?
  • 如果你仍然依赖 2 的补码,x + ~y + 1 is the same thing as x - y。以这种方式重写它不会防止任何溢出。
  • @harold 这正是我的问题!

标签: c logic bitwise-operators bits


【解决方案1】:

[编辑] 错误的解决方案,因为它使用条件。我将暂时搁置它,因为它可能会提供见解。

假设我们知道int 是 4 字节 2 的补码。

if (x == y) return 1;
int SignMask = 0x80000000;
// if x & y have different signs ...
if ((x & SignMask) != (y & SignMask)) {
  return !!(x & SignMask);  
}
// Continue with your original code knowing overflow will not happen.

【讨论】:

    【解决方案2】:

    只是为了练习,以下扭曲的代码将不带任何“+”或条件语句(除非您考虑强制转换为布尔条件)。

    #define MSB 0x80000000
    typedef bool (*RecurseFunc)(unsigned int, unsigned int);
    
    bool EndRecursion(unsigned int ux, unsigned int uy)
    {
        // stop recursion - ux cannot be smaller than uy
        return false;
    }
    
    bool CompareMSB(unsigned int ux, unsigned int uy)
    {
        // jump table, may make global...
        RecurseFunc Handler[2] = {EndRecursion, CompareMSB}; 
    
        // yMsbBigger == MSB only iff Y"MSB==1 and X:MSB==0
        unsigned int yMsbBigger = ((~ux) & uy) & MSB; 
        // differentMsb will be MSB only iff the MSB of Y different MSB of x
        unsigned int differentMsb = (uy ^ ux) & MSB; 
    
        // prepare to check on the next bit - shift it to MSB position
        ux <<= 1;
        uy <<= 1;
    
        // we may want to check the remaining bits if ux,uy had same signs and 
        //     the remaining bits of y are not all 0
        bool mayRecurse = ((bool)uy) && (!(bool)differentMsb); 
    
        // C will not evaluate the second expression if the first is true
        // the second expression will "EndRecursion" if we may not recurse - 
        //     otherwise recurse
        return (((bool)yMsbBigger) || Handler[mayRecurse](ux, uy));
    }
    
    bool isYGreater(int x, int y)
    {
        // we reverse the sign bits so positive value will have MSB=1, making it 
        //     "greater" then negative value's MSB
        unsigned int xbits = (unsigned int)x ^ MSB;
        unsigned int ybits = (unsigned int)y ^ MSB;
    
        return (CompareMSB(xbits, ybits));
    }
    

    【讨论】:

      猜你喜欢
      • 2022-11-25
      • 1970-01-01
      • 1970-01-01
      • 2023-01-26
      • 2014-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多