C中的代字号运算符


95

我已经看到了ELF哈希算法中使用的波浪号运算符,并且很好奇它的作用。(代码来自“永恒困惑”。)

unsigned elf_hash ( void *key, int len )
{
  unsigned char *p = key;
  unsigned h = 0, g;
  int i;

  for ( i = 0; i < len; i++ ) {
    h = ( h << 4 ) + p[i];
    g = h & 0xf0000000L;

    if ( g != 0 )
      h ^= g >> 24;

    h &= ~g;
  }

  return h;
}

Answers:


126

~操作是按位NOT,它反转位二进制数:

NOT 011100
  = 100011

1
按位NOT对许多事物(例如位掩码)有用。我不确定从无符号到有符号整数转换的意思。
GWW

2
等一下,您不应该对位掩码进行“与”吗?这就是我的读卡器的工作方式,但是很棘手。我读到,如果您有X而不是X,然后减去一个,您将获得带符号数字的无符号版本,这是不正确的?
MarcusJ 2015年

2
我在与AND组合的位掩码上使用按位NOT,以在更改特定位之前清除它们。
GWW

2
有人问“未签名到已签名的转换”。所执行的操作~也称为“一个人的补码”,它是二进制求反的一种形式。几乎所有现代计算机都使用二进制补码算术,即按位逆算加一。因此,对于有符号整数变量x,通常会发现它~x + 1提供与相同的值-x。例如,在我的机器上printf("%hx %hx\n", -1234, ~1234 + 1)打印fb2e fb2e
史蒂夫首脑会议

2
@MarcusJ是的,一个人的补码可用于将有符号转换为无符号(signed-> unsigned)。(请注意,尽管将值赋给以不同方式声明的变量会更容易,让编译器担心它。)但是,它却无法正常工作(无符号->有符号),部分原因是可能的无符号值涵盖的范围更广可以将其塞入带符号的变量中,部分原因是,如果没有(可能从外部信息中)指定要发明什么符号,就无法很好地定义该问题。您的两个评论得到了不同的答复,因为它们指定了相反的方向。
Chuck Kollars's

43

~是按位NOT运算符。它将操作数的位取反。

例如,如果您有:

char b = 0xF0;  /* Bits are 11110000 */
char c = ~b;    /* Bits are 00001111 */

12

这是按位NOT运算符。它将数字中的所有位翻转:100110-> 011001


8

代字号字符用作将整数的所有位取反的运算符(按位非)。

例如:~0x0044 = 0xFFBB



1

Tilde运算符(〜)称为按位NOT运算符,它对任何二进制数进行一个补码作为参数。如果到NOT的操作数是十进制数,则将其转换为二进制并执行一个补码运算。

要计算补数,只需将所有数字[0-> 1]和[1-> 0]求反,例如:0101 = 5; 〜(0101)=1010。使用波浪号运算符:1.在屏蔽操作中使用,屏蔽表示在任何寄存器中设置和重置值。对于前:

char mask ;
mask = 1 << 5 ;

它将掩码设置为二进制值10000,此掩码可用于检查其他变量中存在的位值。

int a = 4;
int k = a&mask ; if the 5th bit is 1 , then k=1 otherwise k=0. 

这称为位屏蔽。2.使用屏蔽属性查找任意数量的二进制等效项。

#include<stdio.h>
void equi_bits(unsigned char);
int main()
{
    unsigned char num = 10 ;
    printf("\nDecimal %d is same as binary ", num);
    equi_bits(num);
    return 0; 
} 
void equi_bits(unsigned char n)
{
  int i ; 
  unsigned char j , k ,mask ;
  for( i = 7 ; i >= 0 ; i--)
  {
     j=i;
     mask = 1 << j;
     k = n&mask ; // Masking
     k==0?printf("0"):printf("1");
  }  
}

输出:十进制10与00001010相同

我的观察:对于任何数据类型的最大范围,补码提供的负值将减少1到任何对应的值。例如:
〜1 --------> -2〜2
---------> -3
依此类推...我将使用少量代码段向您展示此观察结果

#include<stdio.h>
int main()
{
    int a , b;
    a=10;
    b=~a; // b-----> -11    
    printf("%d\n",a+~b+1);// equivalent to a-b
    return 0;
}
Output: 0

注意:这仅对数据类型范围有效。对于int数据类型,意味着此规则仅适用于range [-2,147,483,648到2,147,483,647]的值。
谢谢.....可以帮助您

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.