2015-09-11 17 views
6

Ho il seguente codice:~ operatore bit a bit in JavaScript

var a = parseInt('010001',2); 
console.log(a.toString(2)); 
// 10001 
var b = ~a; 
console.log(b.toString(2)); 
// -10010 

The MSDN Say

~ Esegue l'operatore NOT su ogni bit. NON si ottiene il valore invertito (a.k.un complemento di uno) di a.

dovrebbe quindi restituire questo .

This Topic kinda confirm that

Quindi non riesco a capire come possiamo ottenere -10.010 invece? L'unica spiegazione è che il potenziale:

010001 viene negata 101110 ma scrivere questa -10.001 e poi per una ragione oscura mi danno i due complementi e -10.001 -10.010 diventano.

Ma tutto questo è molto oscuro nella mia mente, avresti un'idea su cosa succede precisamente.

+3

sembra che Javascript ritiene che questo sia un 32 bit firmato io nt sotto le coperte. 0b010001 = 0x00000011 o decimale 17. Il complemento di questo è 0xFFFFFFEE, o decimale -18, quando viene trattato come int firmato a 32 bit, che equivale a 0x111111111111111111,1111111111111111. –

+0

Inoltre, 0b10010 è 18 positivo, quindi -0b10010 è -18. –

risposta

2

Sotto le coperte, quando Javascript fa operazioni bit per bit, lo converte in una rappresentazione numero intero con segno a 32 bit, e la utilizza, quindi converte il risultato di nuovo nella sua rappresentazione decimale interna.

Come tale, il valore di input, 010001 diventa 00000000 00000000 00000000 00010001.

Questo viene poi invertito:

~00000000 00000000 00000000 00010001 => 11111111 11111111 11111111 11101110 

convertito in esadecimale, il valore invertito è 0xFFFFFFEE, che è equivalente al valore decimale di -18.

Poiché questo è un numero intero firmato con un valore di -18, questo valore viene convertito sottostante decimale rappresentazione -18 da JavaScript.

Quando Javascript prova a stamparlo come un numero in base 2, si vede il segno negativo e il valore di 18, e stampa come -10010, dal momento che 10010 è la rappresentazione binaria di positivo 18.

+0

Grazie per la risposta Shotgun Ninja. Penso che spieghi cosa mi stava confondendo ... le mie capacità binarie sono arrugginite! :) –

+1

aggiungo questo link molto interessante per capire la conversione del complemento a 2 http://www.wikihow.com/Convert-a-Negative-Binary-to-Decimal –

0

Come da documentazione sul sito dello sviluppatore di Mozilla here. Bitwise NOTing qualsiasi numero x rese - (x + 1). Ad esempio, ~ 5 produce -6. Ecco perché stai ricevendo il segno negativo davanti al numero.

+0

Non so perché i downvotes come questo spiegano perfettamente il problema – musefan

+0

Questo copre i dettagli di ciò che sta realmente accadendo, ma è una buona regola empirica da ricordare. Se l'OP utilizza operazioni bit a bit, è probabilmente più corretto spiegare come funzionano piuttosto che fornire una risposta che li sorvegli per semplicità. –

+0

Questo non spiega _why_, vedi T.J. La risposta di Crowder per una spiegazione migliore. – Nit

3

Gli operatori bitwise di JavaScript convertono i loro operandi in numeri interi a 32 bit (il solito 2's complement), eseguono le loro operazioni, quindi restituiscono il risultato come il valore più appropriato nel tipo di numero JavaScript (virgola mobile a precisione doppia; JavaScript non avere un tipo intero). Altro in §12.5.11 (Bitwise NOT Operator ~) e §7.1.5 (ToInt32).

Così il vostro 10001 è:

 
00000000 00000000 00000000 00010001 

che quando ~ è:

 
11111111 11111111 11111111 11101110 

... che è davvero negativo in 2s complemento di rappresentanza.

Ci si potrebbe chiedere: Se il modello di bit è come sopra, allora perché b.toString(2) ti ha dato -10010 invece? Perché mostra il binario firmato, non il modello di bit effettivo. - significato negativo, e 10010 significato 18 decimale. Il pattern di bit sopra è come viene rappresentato nei bit del complemento 2s. (E sì, io fatto devono andare a controllare me su questo!)

+0

Ma non è -18? – musefan

+1

è, guarda come funziona il complemento a due –

+1

@musefan: Si scopre che non ho i miei bit sbagliati. '11111111 11111111 11111111 11101110' in complemento binario a 2 secondi è -18 decimali. –

1

utilizza Javascript 32-bit numeri firmato, in modo

a (010001) (17) is 0000 0000 0000 0000 0000 0000 0001 0001 
b = ~a (?) (-18) is 1111 1111 1111 1111 1111 1111 1110 1110 

La ragione per la stampa di -18 come -10.010 e metodi per ottenere il valore reale è spiegata bene qui Link

+0

Grazie per l'extra precisione AcidBurn! –