Calcolatrice bitwise
Esegui operazioni bit a bit su interi e visualizza i risultati in decimale, esadecimale e binario.
Come funziona
- Inserisci due numeri: immetti i valori su cui operare, in decimale, binario (prefisso 0b) o esadecimale (prefisso 0x).
- Scegli l'operazione: seleziona AND, OR, XOR, NOT, shift sinistro (<<) o shift destro (>>).
- Consulta il risultato: l'output mostra il risultato in decimale, binario ed esadecimale allo stesso tempo, con una visualizzazione bit a bit.
Perché usare la calcolatrice bit a bit?
Le operazioni bit a bit sono fondamentali nella programmazione di sistema, nella crittografia, nello sviluppo di giochi, nella grafica, nelle reti e nei sistemi embedded. Capire come AND, OR, XOR e gli shift manipolano i singoli bit è cruciale per attivare/disattivare flag, comprimere dati e implementare algoritmi efficienti. Questa calcolatrice mostra l'operazione a livello del bit per vedere esattamente come ogni bit è influenzato.
Funzionalità
- Tutti gli operatori bit a bit: AND (&), OR (|), XOR (^), NOT (~), shift sinistro (<<) e shift destro (>>).
- Input multi-base: inserisci numeri in decimale, binario (0b…) o esadecimale (0x…).
- Output multi-base: i risultati sono mostrati simultaneamente in decimale, binario ed esadecimale.
- Visualizzazione dei bit: una griglia visiva mostra quali bit sono attivi per ogni operando e per il risultato.
- Modalità signed/unsigned: alterna tra interi a 8, 16, 32 e 64 bit.
Domande frequenti
A cosa serve XOR in programmazione?
XOR (^) serve a invertire bit, fare cifratura/offuscamento semplice, scambiare variabili senza variabile temporanea, verificare la parità e mescolare hash. Restituisce 1 quando i bit differiscono e 0 quando sono identici.
Qual è la differenza tra << e >>?
Lo shift sinistro (<<) sposta tutti i bit verso sinistra, equivalente a una moltiplicazione per potenze di 2. Lo shift destro (>>) sposta i bit verso destra, equivalente a una divisione per potenze di 2. Lo shift destro aritmetico preserva il bit di segno; lo shift destro logico riempie con zeri.
Come attivare o disattivare un bit specifico?
Per attivare il bit n: value |= (1 << n). Per disattivare il bit n: value &= ~(1 << n). Per invertire il bit n: value ^= (1 << n). Per verificare se il bit n è attivo: (value & (1 << n)) !== 0.
Dall'algebra booleana al silicio: come le operazioni bit a bit sono diventate universali
Le operazioni bit a bit che ogni CPU moderna implementa provengono da due articoli fondanti pubblicati a più di 80 anni di distanza. Nel 1854, George Boole pubblicò «An Investigation of the Laws of Thought», definendo l'algebra della logica a due valori, AND, OR, NOT e le loro identità. Era un lavoro filosofico, non ingegneristico. Poi nel 1937, uno studente magistrale del MIT di 21 anni chiamato Claude Shannon scrisse la sua tesi magistrale «A Symbolic Analysis of Relay and Switching Circuits», dimostrando che l'algebra booleana poteva descrivere circuiti di relè elettrici e quindi che qualsiasi calcolo logico poteva essere fisicamente implementato. Questa tesi è ampiamente citata come la più importante tesi magistrale del XX secolo ed è il fondamento di tutta l'elettronica digitale. Il complemento a due, la rappresentazione binaria per i numeri negativi che ogni CPU usa, è stato brevettato nel 1962 da Burroughs Corporation ma era stato usato nell'IBM 704 (1954) e altre macchine antiche. IEEE 754 ha standardizzato la rappresentazione in virgola mobile nel 1985, fissando il layout dei bit che ogni Number JavaScript usa ancora, 1 bit di segno, 11 esponente, 52 mantissa per binary64. Oggi, gli operatori del linguaggio C & | ^ ~ << >> mappano quasi direttamente a singole istruzioni CPU, motivo per cui il codice bit a bit può essere drammaticamente più veloce dell'equivalente aritmetico.
I sei operatori, cosa fanno a livello di bit
- AND (
&). Il bit risultato è 1 solo se entrambi i bit di input sono 1.0b1100 & 0b1010 = 0b1000. Usalo per mascherare, isolare bit specifici o verificare se un flag è impostato:flags & FLAG_READè diverso da zero seFLAG_READè attivo. - OR (
|). Il bit risultato è 1 se uno dei bit di input è 1.0b1100 | 0b1010 = 0b1110. Usalo per impostare bit, combinare flag:flags = FLAG_READ | FLAG_WRITE. - XOR (
^). Il bit risultato è 1 se esattamente un bit di input è 1.0b1100 ^ 0b1010 = 0b0110. Usalo per alternare bit, offuscamento semplice (x ^ x = 0, quindi XOR è il suo inverso), parità e mescolanza hash. - NOT (
~). Inverte ogni bit.~0b0000_1111 = 0b1111_0000(in 8 bit). In complemento a due,~xequivale a-x − 1, quindi~5 === -6in JavaScript. - Spostamento a sinistra (
<<). Sposta tutti i bit a sinistra di n posizioni, riempi la destra con zeri.1 << 3 === 8, equivalente a moltiplicare per 2³. Utile per costruire maschere di bit:1 << nè «il bit in posizione n». - Spostamento a destra (
>>aritmetico,>>>logico). Sposta i bit a destra. Lo spostamento aritmetico (>>in JS, Java, C con segno) preserva il bit di segno; lo spostamento logico (>>>in JS,>>in C senza segno) riempie con zeri.-8 >> 1 === -4ma-8 >>> 1 === 2147483644in JavaScript perché>>>coerce prima a un int senza segno a 32 bit.
Dove il bit a bit guadagna davvero il suo stipendio
- Flag di bit e attivazioni di funzionalità. Imballa 32 opzioni booleane in un singolo intero. I permessi dei file Linux (
chmod 755), le intestazioni dei protocolli di rete (TCP, IPv4) e i flag di stato OpenGL usano tutti questo pattern. Un controllo&ti dice se una funzionalità è abilitata. - Permessi dei file Unix.
rwxr-xr-xè0b111_101_101 = 0o755 = 493. I tre gruppi sono utente/gruppo/altro, ogni tre bit sono read/write/execute. Il calcolatore chmod trasforma la forma simbolica nell'intero che la tua shell vuole. - Maschere di sottorete IP. Una maschera
/24è255.255.255.0o0xFFFFFF00. Per verificare se un IP è in una sottorete:(ip & mask) === (network & mask). Usato da ogni router e firewall nel mondo. - Crittografia e hashing. SHA-256, AES, ChaCha20, BLAKE3, ogni hash e cifrario moderno è costruito principalmente da AND, OR, XOR, NOT e rotazioni. Solo XOR è la base dei one-time pad, che sono dimostrabilmente infrangibili quando la chiave è veramente casuale e usata una volta.
- Manipolazione dei colori. Un colore RGBA a 32 bit impacchetta quattro canali a 8 bit:
(R << 24) | (G << 16) | (B << 8) | A. Per estrarre il canale rosso:(color >> 24) & 0xFF. Usato da HTML canvas, OpenGL, ogni formato di immagine. - Trucchi di performance.
x & 1è molto più veloce dix % 2sulla maggior parte delle CPU (un ciclo vs ~10).x >> 1divide per 2 in un ciclo. L'allineamento a potenza di due, i conteggi della popolazione di bit e gli hack di manipolazione dei bit sono ovunque nel codice critico in performance. (Vedi la pagina «Bit Twiddling Hacks» di Sean Anderson per un famoso catalogo.) - Sistemi embedded. I microcontrollori mappano i registri hardware a posizioni di bit specifiche nella memoria. Configurare un UART o un pin GPIO richiede mascheramento e spostamento per leggere o scrivere i bit giusti senza disturbare il resto. La sintassi bitfield di C è zucchero conveniente per questi pattern.
Errori che mordono
- Confondere
&con&&e|con||. Le forme singole sono bit a bit, le doppie sono logiche a corto circuito.1 & 2 === 0(nessun bit condiviso) ma1 && 2 === 2(entrambi truthy, restituisce il secondo). Mescolarli rompe silenziosamente la logica condizionale. - Sorprese di precedenza degli operatori.
x & FLAG === 0significax & (FLAG === 0), non(x & FLAG) === 0, perché===si lega più stretto di&. Metti sempre tra parentesi le espressioni bit a bit nelle condizioni. - Confusione di spostamento con segno vs senza segno. In JavaScript,
>>è aritmetico (estensione del segno),>>>è logico (riempimento con zero). C distingue per il tipo di variabile, i tipi con segno usano aritmetico, senza segno usano logico. Java ha sia>>che>>>come JavaScript. Non far corrispondere la convenzione linguistica inverte silenziosamente il significato. - JavaScript tronca a 32 bit per le operazioni bit a bit. Nonostante
Numbersia un float a 64 bit, tutti gli operatori bit a bit coerciscono prima gli operandi a int32.0x100000000 & 0xFF === 0, non 0 + il byte basso, perché l'operando è troncato a 32 bit prima dell'AND. Per la manipolazione di bit a 64 bit usaBigInt, che ha i suoi operatori bit a bit. - Spostare di > 31 in JavaScript.
1 << 32 === 1, non 0. La quantità di spostamento è presa modulo 32. C è ancora più pericoloso: spostare di più della larghezza dei bit è comportamento indefinito, quindi i compilatori possono fare qualsiasi cosa. Controlla sempren < bitWidthprima di spostare di un valore in fase di esecuzione. - Endianness nel codice di impacchettamento dei byte.
(r << 24) | (g << 16) | (b << 8) | aproduce0xRRGGBBAA. Se i byte sono memorizzati in quell'ordine o invertiti in memoria dipende dalla piattaforma. ImageData in HTML canvas è little-endian su x86; il formato di file PNG è big-endian. Converti esplicitamente conDataViewquando leggi formati binari. - Dimenticare il complemento a due.
~0 === -1, non0xFFFFFFFF, perché tutti-uni è la codifica in complemento a due di −1. Per ottenere l'interpretazione a 32 bit senza segno in JavaScript:(~0) >>> 0 === 4294967295.
Perché il complemento a due, e cosa significa a livello di bit
Ogni CPU moderna rappresenta gli interi negativi usando il complemento a due. In un byte con segno a 8 bit, i valori da 0 a 127 sono codificati come binario 0000_0000 a 0111_1111. Poi −1 è codificato come 1111_1111, −2 come 1111_1110, fino a −128 come 1000_0000. La ragione: con questa codifica, l'addizione funziona allo stesso modo sia che gli input siano con segno o senza segno, la CPU non ha bisogno di istruzioni separate add-with-sign e add-without-sign. L'asimmetria è che l'intervallo negativo è uno più grande di quello positivo (in 8 bit, da −128 a +127), motivo per cui Math.abs(INT_MIN) trabocca in ogni linguaggio con interi a larghezza fissa. Le codifiche precedenti segno-grandezza (un bit per il segno, resto per la grandezza) e complemento a uno esistevano negli anni 1950-60 ma persero contro il complemento a due perché avevano due rappresentazioni dello zero e richiedevano hardware caso speciale per la negazione.
Altre domande frequenti
Perché ~5 è uguale a -6 invece di 250?
Perché in complemento a due (la codifica che ogni CPU moderna usa), invertire ogni bit di un numero positivo ti dà -n - 1. Quindi ~5 === -6 e ~0 === -1. In un contesto senza segno a 8 bit, lo stesso pattern di bit di ~5 (binario 1111_1010) rappresenterebbe 250. JavaScript tratta il risultato come signed 32 bit, quindi vedi -6. Per ottenere l'interpretazione senza segno: (~5) >>> 0 in 32 bit, che dà 4294967290, o mascherare a 8 bit con ~5 & 0xFF che dà 250.
XOR è davvero una crittografia?
XOR è il blocco di costruzione di ogni cifrario simmetrico moderno, ma solo XOR non è crittografia sicura. Un one-time pad, XOR con una chiave veramente casuale lunga quanto il messaggio, usata esattamente una volta, è teoricamente delle informazioni infrangibile (Shannon, 1949). Riutilizza la chiave, o usa una chiave più corta del messaggio, e l'analisi della frequenza lo rompe banalmente. I cifrari reali come AES usano XOR più diffusione e sostituzione per amplificare una chiave corta in un flusso di byte pseudo-casuali che sembra un one-time pad a chiunque senza la chiave. Quindi «cifrare con XOR» va bene solo per offuscamento banale, mai per segreti reali.
Quando dovrei usare BigInt invece di Number per la manipolazione dei bit?
Ogni volta che hai bisogno di più di 32 bit di precisione bit a bit. Gli operatori bit a bit JavaScript troncano gli operandi Number a interi con segno a 32 bit prima del calcolo. Se hai bisogno di maschere a 64 bit (e.g., manipolare un set di flag di funzionalità a 64 bit, lavorare con offset Linux mmap, o implementare SHA-512), usa BigInt: 0xFFFFFFFFFFFFFFFFn & 0xFFn === 255n. BigInt è più lento di Number, ~3-10× a seconda dell'operazione, quindi riservalo per i casi in cui 32 bit sono genuinamente troppo pochi.
Come conto il numero di bit 1 in un numero?
Questo è il conteggio della popolazione o peso di Hamming. La maggior parte delle CPU moderne ha una singola istruzione per esso (POPCNT su x86, VCNT su ARM). In JavaScript, nessun built-in, quindi usa il classico di manipolazione dei bit: let c = 0; while (x) { c += x & 1; x >>>= 1; }. O il trucco SWAR parallelo da Hacker's Delight: x = x - ((x >> 1) & 0x55555555); x = (x & 0x33333333) + ((x >> 2) & 0x33333333); x = (x + (x >> 4)) & 0x0F0F0F0F; return (x * 0x01010101) >>> 24;, che conta i bit in un intero a 32 bit in circa una dozzina di cicli.
I miei dati vengono inviati da qualche parte quando uso questo calcolatore?
No. Ogni operazione gira nel motore JavaScript del tuo browser, nessuna chiamata di rete avviene durante un calcolo. Apri la scheda Rete in DevTools e clicca Calcola, vedrai zero richieste in uscita. Sicuro per maschere sensibili, chiavi o lavoro proprietario di layout dei bit.