如何使用位运算符表示否定,C

如何使用位运算符表示否定,C,c,operators,bit-manipulation,C,Operators,Bit Manipulation,假设您有两个数字: int x = 1; int y = 2; 使用位运算符,如何表示x-y?您需要了解算术知识。加法、减法、求反、符号测试以及其他所有操作都是由硬件使用位运算完成的,因此您完全可以在C程序中完成。上面的维基百科链接应该教会你解决问题所需的一切知识。你需要阅读有关算术的知识。加法、减法、求反、符号测试以及其他所有操作都是由硬件使用位运算完成的,因此您完全可以在C程序中完成。上面的wikipedia链接应该教会您解决问题所需的一切知识。您的第一步将是仅使用位运算符实现加法。在那之

假设您有两个数字:

int x = 1;
int y = 2;

使用位运算符,如何表示x-y?

您需要了解算术知识。加法、减法、求反、符号测试以及其他所有操作都是由硬件使用位运算完成的,因此您完全可以在C程序中完成。上面的维基百科链接应该教会你解决问题所需的一切知识。

你需要阅读有关算术的知识。加法、减法、求反、符号测试以及其他所有操作都是由硬件使用位运算完成的,因此您完全可以在C程序中完成。上面的wikipedia链接应该教会您解决问题所需的一切知识。

您的第一步将是仅使用位运算符实现加法。在那之后,一切都应该很容易。从小处做起-要实现00+00、01+01等,您必须做些什么?从这里开始。

您的第一步将是仅使用位运算符实现加法。在那之后,一切都应该很容易。从小处做起-要实现00+00、01+01等,您必须做些什么?从那里开始。

当比较两个数字
A
B
的位时,有三种可能性。以下假定为无符号数字

  • A==B
    :所有位都相同
  • A>B
    :两个数字之间差异的最高有效位设置在
    A
    中,而不是
    B
  • A
    :两个数字之间不同的最高有效位设置在
    B
    中,而不是
    A
  • 代码可能如下所示

    int getDifType(uint32_t A, uint32_t B)
    {
      uint32_t bitMask = 0x8000000;
      // From MSB to LSB
      for (bitMask = 0x80000000; 0 != bitMask; bitMask >>= 1)
      {
        if (A & bitMask != B & bitMask)
          return (A & bitMask) - (B & bitMask);
      }
      // No difference found
      return 0;
    }
    

    比较两个数字
    A
    B
    的位时,有三种可能性。以下假定为无符号数字

  • A==B
    :所有位都相同
  • A>B
    :两个数字之间差异的最高有效位设置在
    A
    中,而不是
    B
  • A
    :两个数字之间不同的最高有效位设置在
    B
    中,而不是
    A
  • 代码可能如下所示

    int getDifType(uint32_t A, uint32_t B)
    {
      uint32_t bitMask = 0x8000000;
      // From MSB to LSB
      for (bitMask = 0x80000000; 0 != bitMask; bitMask >>= 1)
      {
        if (A & bitMask != B & bitMask)
          return (A & bitMask) - (B & bitMask);
      }
      // No difference found
      return 0;
    }
    

    您需要从最重要的一端开始检查,以确定某个数字是否大于该数字。此逻辑仅适用于非负整数

    int x,y;
    //get x & y
    unsigned int mask=1;           // make the mask 000..0001
    mask=mask<<(8*sizeoF(int)-1);    // make the mask 1000..000
    
    while(mask!=0)             
    {
    if(x & mask > y & mask)        
    {printf("x greater");break;}
    else if(y & mask > x & mask)
    {printf("y greater");break;}
    mask=mask>>1;                  // shift 1 in mask to the right
    }
    
    intx,y;
    //得到x&y
    无符号整数掩码=1;//制作面具000..0001
    遮罩=遮罩x和遮罩)
    {printf(“y更大”);break;}
    掩码=掩码>>1;//将遮罩中的1移到右侧
    }
    
    您需要从最重要的一端开始检查,以确定数字是否大于。此逻辑仅适用于非负整数

    int x,y;
    //get x & y
    unsigned int mask=1;           // make the mask 000..0001
    mask=mask<<(8*sizeoF(int)-1);    // make the mask 1000..000
    
    while(mask!=0)             
    {
    if(x & mask > y & mask)        
    {printf("x greater");break;}
    else if(y & mask > x & mask)
    {printf("y greater");break;}
    mask=mask>>1;                  // shift 1 in mask to the right
    }
    
    intx,y;
    //得到x&y
    无符号整数掩码=1;//制作面具000..0001
    遮罩=遮罩x和遮罩)
    {printf(“y更大”);break;}
    掩码=掩码>>1;//将遮罩中的1移到右侧
    }
    
    从左到右比较位,查找最左边不同的位。假设一台机器是两位的补码,最上面的一位决定符号,与其他位相比将具有翻转的比较意义。这应该适用于任何两个的补码机:

    int compare(int x, int y) {
      unsigned int mask = ~0U - (~0U >> 1); // select left-most bit
      if (x & mask && ~y & mask)
        return -1; // x < 0 and y >= 0, therefore y > x
      else if (~x & mask && y & mask)
        return 1; // x >= 0 and y < 0, therefore x > y
      for (; mask; mask >>= 1) {
        if (x & mask && ~y & mask)
          return 1;
        else if (~x & mask && y & mask)
          return -1;
      }
      return 0;
    }
    
    int比较(int x,int y){
    无符号整数掩码=~0U-(~0U>>1);//选择最左边的位
    if(x和掩码&&&y和掩码)
    返回-1;//x<0且y>=0,因此y>x
    else if(~x&mask&&y&mask)
    返回1;//x>=0且y<0,因此x>y
    对于(;掩码;掩码>>=1){
    if(x和掩码&&&y和掩码)
    返回1;
    else if(~x&mask&&y&mask)
    返回-1;
    }
    返回0;
    }
    
    [请注意,这在技术上是不可移植的。C不能保证有符号算术是二的补码。但在现代机器上很难找到行为不同的C实现。]

    看看为什么这样做,首先考虑比较两个无符号数,13d= 1101b和11d= 1011b。(为了简洁起见,我假设字号为4位。)最左边的不同位是从左边算起的第二位,前者已设置,而另一位未设置。因此,前者的数字更大。很明显,这一原则适用于所有无符号数字


    现在,考虑两个补数。你可以通过补位加一来求反。因此,-1d=1111b,-2d=1110b,-3d=1101b,-4d=1100b等等。您可以看到两个负数可以进行比较,就好像它们是无符号的一样。同样,两个非负数也可以进行比较,就好像没有符号一样。只有当符号不同的时候,我们必须考虑它们——但是如果它们不同,比较是微不足道的! 从左到右比较位,查找最左边不同的位。假设一台机器是两位的补码,最上面的一位决定符号,与其他位相比将具有翻转的比较意义。这应该适用于任何两个的补码机:

    int compare(int x, int y) {
      unsigned int mask = ~0U - (~0U >> 1); // select left-most bit
      if (x & mask && ~y & mask)
        return -1; // x < 0 and y >= 0, therefore y > x
      else if (~x & mask && y & mask)
        return 1; // x >= 0 and y < 0, therefore x > y
      for (; mask; mask >>= 1) {
        if (x & mask && ~y & mask)
          return 1;
        else if (~x & mask && y & mask)
          return -1;
      }
      return 0;
    }
    
    int比较(int x,int y){
    无符号整数掩码=~0U-(~0U>>1);//选择最左边的位
    if(x和掩码&&&y和掩码)
    返回-1;//x<0且y>=0,因此y>x
    else if(~x&mask&&y&mask)
    返回1;//x>=0且y<0,因此x>y
    对于(;掩码;掩码>>=1){
    if(x和掩码&&&y和掩码)
    返回1;
    else if(~x&mask&&y&mask)
    返回-1;
    }
    返回0;
    }
    
    [请注意,这在技术上是不可移植的。C不能保证有符号算术是二的补码。但在现代机器上很难找到行为不同的C实现。]

    看看为什么这样做,首先考虑比较两个无符号数,13d= 1101b和11d= 1011b。(为了简洁起见,我假设字号为4位。)最左边的不同位是从左边算起的第二位,前者已设置,而另一位未设置。因此,前者的数字更大。应该相当清楚的是