L'operatore tilde in C


95

Ho visto l'operatore tilde utilizzato nell'algoritmo di hashing ELF e sono curioso di cosa fa. (Il codice proviene da 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;
}

Risposte:


126

L' ~operatore è NOT bit per bit , inverte i bit in un numero binario:

NOT 011100
  = 100011

1
Bitwise NOT è utile per una serie di cose, ad esempio, maschere di bit. Non sono sicuro di cosa intendi per conversione da intero non firmato a intero con segno.
GWW

2
Aspetta, non dovresti E la maschera di bit? è così che lo fa il mio lettore di bit, ma è permaloso. Ho letto che se hai X e NON, quindi sottrai uno otterrai la versione non firmata di un numero firmato, non è corretto?
MarcusJ

2
Uso NOT bit per bit su una maschera di bit in combinazione con AND per cancellare bit specifici prima di modificarli.
GWW

2
Qualcuno ha chiesto informazioni sulla "conversione da non firmato a firmato". L'operazione eseguita da ~è anche chiamata "complemento a uno", che è una forma di negazione binaria. Praticamente tutti i computer moderni usano l'aritmetica in complemento a due, che è l'inverso bit per bit, più uno. Quindi, per una variabile intera con segno x, troverai in genere che ~x + 1fornisce lo stesso valore di -x. Ad esempio, printf("%hx %hx\n", -1234, ~1234 + 1)stampa fb2e fb2esulla mia macchina.
Steve Summit

2
@MarcusJ Sì, il complemento di uno funziona per convertire firmato in non firmato (firmato-> non firmato). (Nota anche se è più semplice assegnare il valore a una variabile dichiarata in modo diverso e lasciare che il compilatore se ne preoccupi.) Ma non funziona al contrario (unsigned-> signed), in parte perché i possibili valori senza segno coprono un intervallo più ampio che può essere stipato in una variabile con segno, e in parte perché quel problema non è ben definito senza specificare - probabilmente da informazioni esterne - quale segno inventare. I tuoi due commenti hanno ricevuto risposte diverse perché specificano direzioni opposte.
Chuck Kollars

43

~è l'operatore NOT bit per bit. Inverte i bit dell'operando.

Ad esempio, se hai:

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

12

Questo è l'operatore NOT bit per bit. Capovolge tutti i bit in un numero: 100110 -> 011001


8

Il carattere tilde viene utilizzato come operatore per invertire tutti i bit di un intero (NOT bit a bit).

Ad esempio: ~0x0044 = 0xFFBB.



1

Operatore tilde (~) chiamato anche operatore NOT bit per bit, esegue il complemento di qualsiasi numero binario come argomento. Se l'operando su NOT è un numero decimale, lo converte in binario ed esegue l'operazione di complemento a uno.

Per calcolare il proprio complemento è sufficiente invertire tutte le cifre [0 -> 1] e [1 -> 0] Es: 0101 = 5; ~ (0101) = 1010. Uso dell'operatore tilde: 1. Viene utilizzato nelle operazioni di mascheramento. Mascherare significa impostare e resettare i valori all'interno di qualsiasi registro. per es:

char mask ;
mask = 1 << 5 ;

Imposta la maschera su un valore binario di 10000 e questa maschera può essere utilizzata per controllare il valore del bit presente all'interno di altre variabili.

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

Questo è chiamato mascheramento dei bit. 2.Per trovare l'equivalente binario di qualsiasi numero utilizzando le proprietà di mascheramento.

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

Risultato: il decimale 10 è uguale a 00001010

La mia osservazione : per l'intervallo massimo di qualsiasi tipo di dati, il complemento di uno fornisce il valore negativo diminuito di 1 a qualsiasi valore corrispondente. es:
~ 1 --------> -2
~ 2 ---------> -3
e così via ... ti mostrerò questa osservazione usando un piccolo frammento di codice

#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

Nota: questo è valido solo per l'intervallo del tipo di dati. significa che per il tipo di dati int questa regola sarà applicabile solo per il valore dell'intervallo [da -2,147,483,648 a 2,147,483,647].
Grazie ..... Possa questo aiutarti

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.