2011-12-04 18 views
9

In C perché non esiste un identificatore standard per stampare un numero nel suo formato binario, come %b. Certo, si possono scrivere alcune funzioni/hack per farlo, ma voglio sapere perché una cosa così semplice non è una parte standard della lingua.Rappresentazione binaria in C

C'è stata una decisione di progettazione dietro di esso? Poiché ci sono specificatori di formato per ottale% o e% x per esadecimale, è che ottale ed esadecimale sono in qualche modo "più importanti" della rappresentazione binaria.

Poiché in C/C++ si incontra spesso operatori bit immagino che sarebbe utile avere %b o immettere direttamente una rappresentazione binaria di un numero in una variabile (il modo in cui si Ingressi numeri esadecimali come int i=0xf2)

Nota: Thread come this discutono solo della parte "come" di fare questo e non il "perché"

+4

Perché stampare binari se è possibile stampare hex? È fondamentalmente la stessa cosa, ma con una densità del 400%. Basta tradurre, '0 = 0000',' 1 = 0001', '2 = 0010', ...,' F = 1111'. –

+0

@ KerrekSB - Solo perché non è così difficile da fare da soli non è un motivo valido per escluderlo dalla lingua. È difficile passare dalla scrittura a uno stream alla scrittura in un buffer di stringa, tradurre e quindi scrivere su uno stream. –

+0

@TedHopp: una volta si poteva discutere l'altro modo perché sarebbe * necessario * essere necessario. Potresti chiedere che vengano inclusi tutti i tipi di materiale (base-4? Base-64?), Ma alla fine non esiste una risposta giusta o sbagliata. I progettisti probabilmente non pensavano che fosse necessario. Immagino che il fatto che chiunque fosse nel business della manipolazione binaria sarebbe sufficientemente esperto in esadecimale ... –

risposta

3

Il motivo principale è "storia", credo. Gli implementatori originali di printf() e altri AT & T non avevano bisogno di binario, ma avevano bisogno di ottale ed esadecimale (oltre che decimale), quindi questo è stato implementato. Lo standard C89 era abbastanza attento a standardizzare la pratica esistente - in generale. C'erano un paio di nuove parti (impostazioni locali e, naturalmente, prototipi di funzione, anche se c'era C++ per fornire "esperienza di implementazione" per quelli).

È possibile leggere numeri binari con strtol() et al; specificare una base di 2. Non credo che ci sia un modo conveniente per formattare numeri in basi diverse (diverse da 8, 10, 16) che è l'inverso di strtol() - presumibilmente dovrebbe essere ltostr().

+3

"Gli implementatori originali di printf() e altri di AT & T non avevano bisogno di binari, ma avevano bisogno di ottale ed esadecimale (oltre che decimale), quindi è quello che è stato implementato." - Hai qualche prova per questo reclamo? Si potrebbe anche dire che volevano semplicemente che avessimo difficoltà a eseguire il debug delle operazioni bit. "Non penso che ci sia un modo conveniente per formattare i numeri in basi diverse" - Perché pensi questo? Di nuovo, rivendichi le cose senza alcuna spiegazione. – kol

+0

Se gli implementatori avessero avuto bisogno dell'output binario, sarebbe stato fornito. Non è stato fornito; è ragionevole dedurre che non ne hanno avuto bisogno. Il manuale UNIX della 7a edizione (disponibile online) non ha alcun supporto per convertire stringhe di cifre binarie in numeri interi. Per quanto riguarda la "formattazione dei numeri in basi diverse", vi rimando allo standard C: esiste una funzione nello standard che consente di formattare un numero in base 2 o base 36? Io non la penso così Se vuoi citare un contro-esempio, dai un nome alla funzione; è facile fornire la prova che ho torto se sbaglio. –

+0

Ricorda: UNIX è stato scritto dalle persone che hanno utilizzato il sistema. Si sono forniti (e noi) con gli strumenti che hanno soddisfatto i loro requisiti. –

1

Una risposta può essere che la formattazione esadecimale è molto più compatta. Vedi ad esempio la vista hexa del Lister di Total Commander.

% b sarebbe utile in molti casi pratici. Ad esempio, se si scrive codice per analizzare i pacchetti di rete, è necessario leggere i valori dei bit, e se printf avrebbe% b, il debug di tale codice sarebbe molto più semplice. Anche se omettere% b potrebbe essere spiegato quando è stato progettato printf, è stata decisamente una cattiva idea.

3

Si chiede "perché" come se ci debba essere una ragione chiara e convincente, ma la realtà è che non esiste un motivo tecnico per non supportare un formato %b.

K & R C è stato creato essere persone che hanno incorniciato la lingua per soddisfare quelli che pensavano sarebbero stati i loro casi di uso comune. Una forza opposta stava cercando di mantenere le specifiche del linguaggio il più semplice possibile.

ANSI C era standardizzato da un comitato i cui membri avevano interessi diversi. Chiaramente lo %b non è stato considerato una priorità vincente.

Le lingue sono fatte da uomini.

2

Il motivo principale per cui vedo che cosa dovrebbe essere una rappresentazione binaria? il proprio complemento? complemento a due? stai aspettando i bit effettivi in ​​memoria o la rappresentazione del numero astratto?

Solo quest'ultimo ha senso quando C non richiede requisiti per la dimensione della parola o la rappresentazione del numero binario. Quindi visto che non sarebbero i bit in memoria, sicuramente preferiresti leggere il numero astratto in hex?

Rivendicazione una rappresentazione astratta è "binario" potrebbe portare alla convinzione che -0b1^0b1 == 0 potrebbe essere vero, o che -0b1 | -0b10 == -0b11


rappresentazioni possibili:

Mentre non v'è solo una rappresentazione esadecimale significativa - - quello astratto, il numero -0x79 può essere rappresentato in binario come:

  • -1111001 (il numero astratto)
  • 11111001 (complemento a uno)
  • 10000111 (complemento a due)

@Eric mi ha convinto che endianness! = Da sinistra a destra ordine ...

il problema è ulteriormente aggravato quando i numeri non si adattano in un byte. lo stesso numero potrebbe essere:

  • 1000000001111001 come complemento per provare le proprie big-endian numero 16bit
  • 1111111110000111 come un complemento a due big-endian numero 16bit
  • 1000011110000000 come uno di -complementare numero little-endian 16bit
  • 1000011111111111 come numero a due bit di little-endian a 16 bit

I concetti di endianità e rappresentazione binaria non si applicano ai numeri esadecimali in quanto non è possibile che possano essere considerati la rappresentazione di bit in memoria effettiva.

Tutti questi esempi presuppongono un byte a 8-bit, che C non fornisce alcuna garanzia di (macchine storiche in effetti ci sono stati con i byte 10 bit)


Perché nessuna decisione è meglio di qualsiasi decisione:

Ovviamente si può scegliere arbitrariamente una rappresentazione o lasciarla definita. Tuttavia:

  • se si sta cercando di usare questo per eseguire il debug di bit per bit operazioni, (che io vedo come l'unico motivo valido per usare binario sopra hex) che si desidera utilizzare qualcosa di simile quello che utilizza l'hardware, il che lo rende impossibile da standardizzare, quindi si desidera definire l'implementazione.
  • Al contrario, se si sta tentando di leggere una sequenza di bit, è necessario un formato standard, non definito dall'implementazione.
  • E sicuramente vuoi che printf e scanf usino lo stesso.

Quindi a me sembra che non ci sia un mezzo felice.

+1

Come è "quale rappresentazione binaria dovrei usare" diversa da "quale rappresentazione esadecimale dovrei usare? "? – Eric

+0

@Eric perché c'è solo una rappresentazione esadecimale --- quella astratta. vedi la mia modifica – tobyodavies

+0

Endianess non è correlata ai concetti di destra o sinistra - puoi scegliere qualunque ordine ti piaccia per visualizzare i bit.Se scrivo '0xAACC', questo è univocamente' 0b1010101011001100'. Continuo a non seguire ciò che rende binario in una classe diversa da esadecimale, quando c'è una mappatura 1 a 1 tra di loro. – Eric

0

Sono d'accordo. Ero un partecipante al comitato ANSI C originale e ho fatto la proposta di includere una rappresentazione binaria in C. Tuttavia, sono stato respinto, per alcune delle ragioni sopra menzionate, anche se penso ancora che sarebbe molto utile quando si fa, ad es. , operazioni bit a bit, ecc.

Vale la pena notare che il comitato ANSI era composto per la maggior parte da sviluppatori di compilatori, non da utenti e programmatori C. I loro obiettivi erano di rendere lo standard comprensibile agli sviluppatori di compilatori non necessariamente per i programmatori C, e di essere in grado di farlo con un documento che non era più necessario, anche se ciò significava che era una lettura difficile per i programmatori C.

Problemi correlati