Оператор тильди в С


95

Я бачив оператор tilde, який використовується в алгоритмі хешування 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;
}

Відповіді:


126

~Оператор побітовое НЕ , він інвертує біти у вигляді двійкового числа:

NOT 011100
  = 100011

1
Побітовий НЕ корисний для ряду речей, наприклад, бітових масок. Я не впевнений, що ви маєте на увазі під підписанням цілочислової конверсії без підпису.
GWW

2
Зачекайте, чи не варто вам І бітмаска? ось так це робить мій маленький читач, але це дотично. Я читав, що якщо у вас є X, а НЕ його, тоді відніміть один, і ви отримаєте непідписану версію підписаного номера, чи не так?
MarcusJ

2
Я використовую побітові НЕ на бітовій масці в поєднанні з І для очищення конкретних бітів до зміни їх.
GWW

2
Хтось запитав про "конверсію без підпису". Операція, яку виконує, ~також називається "доповненням", що є однією з форм бінарного заперечення. Практично всі сучасні комп’ютери використовують арифметику комплементу двох, яка є побітною оберттю плюс один. Таким чином, для підписаної цілочисельної змінної xви зазвичай знайдете те, що ~x + 1дає те саме значення, що і -x. Наприклад, printf("%hx %hx\n", -1234, ~1234 + 1)відбитки fb2e fb2eна моїй машині.
Стів Саміт

2
@MarcusJ Так, доповнення працює для перетворення підписаного в непідписане (підпис-> без підпису). (Зверніть увагу, хоча простіше просто присвоїти значення змінній, оголошеній по-іншому, і дозволити компілятору турбуватися про це.) Але це не працює навпаки (непідписаний-> підписаний), частково тому, що можливі неподписані значення охоплюють ширший діапазон ніж можна зафіксувати підписану змінну, і почасти тому, що ця проблема недостатньо чітко визначена без вказівки -від зовнішньої інформації, ймовірно, який знак вигадати. Ваші два коментарі отримали різні відповіді, оскільки вони визначають протилежні напрямки.
Чак Колларс

43

~є побітним оператором НЕ. Він інвертує біти операнда.

Наприклад, якщо у вас є:

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


8

Символ тильди використовується як оператор для інвертування всіх бітів цілого числа (порозрядне НЕ).

Наприклад: ~0x0044 = 0xFFBB.



1

Оператор Тильди (~), який також називається побітовим оператором 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 це правило застосовуватиметься лише до значення діапазону [-2,147,483,648 до 2,147,483,647].
Дякую ..... Нехай це допоможе тобі

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.