Toán tử dấu ngã trong C


95

Tôi đã thấy toán tử dấu ngã được sử dụng trong thuật toán băm ELF và tôi tò mò không biết nó có tác dụng gì. (Mã là từ Eternally Confused .)

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;
}

Câu trả lời:


126

Các ~nhà điều hành là Bitwise NOT , nó sẽ đảo ngược các bit trong một số nhị phân:

NOT 011100
  = 100011

1
Bitwise NOT hữu ích cho một số thứ, ví dụ, mặt nạ bit. Tôi không chắc ý bạn là gì khi chuyển đổi số nguyên không dấu thành có dấu.
GWW

2
Chờ đã, bạn không nên VÀ bitmask? đó là cách mà người đọc bit của tôi đang làm, nhưng nó khá rắc rối. Tôi đọc rằng nếu bạn có X và KHÔNG nó, sau đó trừ đi một khoản, bạn sẽ nhận được phiên bản không dấu của một số có dấu, điều đó không chính xác phải không?
MarcusJ

2
Tôi sử dụng bitwise NOT trên bitmask kết hợp với AND để xóa các bit cụ thể trước khi thay đổi chúng.
GWW

2
Có người hỏi về "chuyển đổi chưa ký sang đã ký". Phép toán được thực hiện bởi ~còn được gọi là "phần bổ sung của một người", là một dạng của phủ định nhị phân. Hầu như tất cả các máy tính hiện đại đều sử dụng số học bổ sung của hai, là phép nghịch đảo bit, cộng với một. Vì vậy, đối với một biến số nguyên có dấu x, bạn thường sẽ thấy rằng nó ~x + 1cung cấp cùng một giá trị như -x. Ví dụ: printf("%hx %hx\n", -1234, ~1234 + 1)bản in fb2e fb2etrên máy của tôi.
Steve Summit

2
@MarcusJ Có, phần bổ sung của một người hoạt động để chuyển đổi có dấu thành không dấu (đã ký-> không dấu). (Lưu ý rằng mặc dù sẽ dễ dàng hơn khi chỉ định giá trị cho một biến được khai báo khác và để trình biên dịch lo lắng về nó.) Nhưng nó không hoạt động theo cách khác (unsigned-> có dấu), một phần vì các giá trị không dấu có thể nằm trong phạm vi rộng hơn hơn có thể được nhồi nhét vào một biến có dấu, và một phần là do vấn đề đó không được xác định rõ ràng mà không xác định -từ thông tin bên ngoài có lẽ- dấu hiệu nào cần phát minh. Hai nhận xét của bạn nhận được phản hồi khác nhau vì chúng chỉ định hướng ngược lại.
Chuck Kollars

43

~là toán tử NOT bitwise. Nó đảo ngược các bit của toán hạng.

Ví dụ: nếu bạn có:

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

12

Đây là toán tử NOT bitwise. Nó lật tất cả các bit thành một số: 100110 -> 011001


8

Ký tự dấu ngã được sử dụng như một toán tử để đảo ngược tất cả các bit của một số nguyên (KHÔNG theo chiều kim bit).

Ví dụ: ~0x0044 = 0xFFBB.


7

Nó là toán tử NOT bitwise. Nó đảo ngược tất cả các bit trong một giá trị số nguyên.


1

Toán tử dấu ngã (~) còn được gọi là toán tử NOT bitwise, thực hiện phần bổ sung của một số nhị phân bất kỳ dưới dạng đối số. Nếu toán hạng thành NOT là số thập phân thì nó chuyển nó thành số nhị phân và thực hiện phép toán bổ sung của một người.

Để tính toán phần bù của một người chỉ cần đảo ngược tất cả các chữ số [0 -> 1] và [1 -> 0] Ví dụ: 0101 = 5; ~ (0101) = 1010. Sử dụng toán tử dấu ngã: 1. Nó được sử dụng trong hoạt động tạo mặt nạ, Tạo mặt nạ có nghĩa là thiết lập và đặt lại các giá trị bên trong bất kỳ thanh ghi nào. cho người yêu cũ:

char mask ;
mask = 1 << 5 ;

Nó sẽ đặt mặt nạ thành giá trị nhị phân 10000 và mặt nạ này có thể được sử dụng để kiểm tra giá trị bit có bên trong biến khác.

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

Đây được gọi là Mặt nạ các bit. 2.Để tìm số tương đương nhị phân của bất kỳ số nào bằng cách sử dụng thuộc tính che.

#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");
  }  
}

Đầu ra: Số thập phân 10 giống với 00001010

Quan sát của tôi : Đối với phạm vi tối đa của bất kỳ loại dữ liệu nào, phần bổ sung của một người cung cấp giá trị âm giảm 1 xuống bất kỳ giá trị tương ứng nào. ví dụ:
~ 1 --------> -2
~ 2 ---------> -3
, v.v. Tôi sẽ cho bạn thấy quan sát này bằng cách sử dụng đoạn mã nhỏ

#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

Lưu ý: Điều này chỉ hợp lệ cho phạm vi kiểu dữ liệu. có nghĩa là đối với kiểu dữ liệu int, quy tắc này sẽ chỉ áp dụng cho giá trị của dải ô [-2,147,483,648 đến 2,147,483,647].
Cảm ơn bạn ..... Điều này có thể giúp bạn

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.