Gibt es eine Möglichkeit, Halbbits zu verwenden?

Wie die meisten Leute hier wissen, können wir mit 4 Bits von 0 bis 15 zählen (0123456789ABCDEF in Hexadezimal). Aber wenn wir nur bis 9 zählen würden, würden wir immer noch 4 Bits verwenden, und die Ziffern von A bis F wären verschwendet.

Auf der QR-Code-Seite von Wikipedia heißt es jedoch, dass die Verwendung von nur numerischen Ziffern von 0 bis 9 3⅓ Bits pro Zeichen verbraucht, was aus statistischer Sicht korrekt ist. Und doch ist ein Drittel eines Bits kein physisches Objekt, und das Senden einer Zahl von 0 bis 9 verwendet meines Wissens mindestens 4 Bits.

Gibt es eine Möglichkeit, die verschwendeten Kombinationen zu verwenden, um ein Zeichen mit Bruchteilen von Bits effektiv zu senden?

OK, ich gebe ein Beispiel: Es müssen die zwei Ziffern „27“ gesendet werden. Bei normalen Codiertechniken wären die gesendeten Bits 00100111. Wir könnten uns dann ein System vorstellen, das die Ziffer „2“ durch die Ziffer „E“ oder „F“ ersetzen würde, je nach dem nächsten Bit; In diesem Fall ist das nächste Bit 0, also wird die '2' durch 'E' ersetzt. Die resultierende Bitfolge wäre dann 1101 0 111. Wenn andererseits die Ziffern „28“ gesendet werden müssen, ist das erste Bit nach der „2“ eine 1, also wird es stattdessen durch die Ziffer „F“ ersetzt, ergibt die Zeichenfolge 1111 1 000.

In beiden Fällen wurde eine Einsparung von 1 Bit bewirkt, weil ein Halbbyte für zwei verschiedene Zeichen verwendet wurde. Mit anderen Worten, für jedes Zeichen werden dreieinhalb Bits verwendet.

Für eine andere Perspektive zum Packen von Werten in einen kleineren Ziffernraum, schauen Sie sich Ternary Computers ( en.wikipedia.org/wiki/Ternary_computer ) an. Wenn es gut genug für Knuth ist, ist es gut genug für mich!
Noch besser ist es zu erkennen, dass Sie das in 7 Bits berechnen (10 * first_digit) + second_digitund codieren können, die 0 ... 99 darstellen, wobei die Codes 100-127 für andere Dinge übrig bleiben. Und es gibt sogar noch mehr Einsparungen mit 3 Ziffern komprimiert in 10 Bit.
Um alle 100 verschiedenen Werte separat zu senden, ist das Beste, was Sie bekommen können, das Packen in 7 Bits. Wenn Sie mehr Ziffern haben, ist das Packen effizienter. Wenn Sie weniger als 64 Werte zu senden haben, können Sie diese mit nur 6 Bits senden

Antworten (10)

Sie können kein halbes Bit senden, aber Sie können effektiv zwei halbe Bits vor der Übertragung oder Speicherung in ein Bit packen.

Sie geben selbst ein Beispiel, also haben Sie Ihre eigene Frage effektiv mit JA beantwortet.

Ein vielleicht etwas einfacherer Weg ist es, den Wert von zwei Dezimalziffern einfach in 7 Bit zu codieren. (Art von binär codiertem Dual-Dezimal).

Ein netter Anwendungsfall für das Packen von Ziffernpaaren in sieben Bits ist die Übertragung von ASCII-Dateien, die hauptsächlich aus numerischen Daten bestehen. Jeder Bytewert unter 128 stellt ein einzelnes ASCII-Zeichen dar, während 128-227 zwei ASCII-Ziffern darstellen. Einfach zu codieren oder zu decodieren und erfordert nicht, dass die Daten hauptsächlich Ziffern (oder sogar irgendwelche Ziffern) enthalten, sondern kann Ziffernfolgen sehr einfach um 50 % komprimieren.
Oder das PDP11-Format, das 3 alphanumerische Zeichen in 16 Bit mit einem Bit übrig packte ...
@BrianDrummond: Man könnte 16 Bits verwenden, um genau drei Zeichen aus einem Satz von 40 oder bis zu drei Zeichen aus einem Satz von 39 zu speichern, aber es gäbe kein Ersatzbit. Normalerweise würde "alphanumerisch" eine Menge von mindestens 36 implizieren, aber die einzige Möglichkeit, ein Ersatzbit zu haben, wäre, wenn die Menge auf 32 begrenzt wäre.
Ich dachte, es wären 5 Bits/Zeichen. Alphanumeric wurde auf zwei Codesets aufgeteilt, wobei ein Symbol für "Switch Code Set" reserviert war. Ich habe mich geirrt: en.wikipedia.org/wiki/DEC_Radix-50 Freakig genug, sah es nur eines Nachts, als ich einen Bericht entschlüsseln musste, den mir jemand auf einer 8-Zoll-Diskette auf einem CP / M-System mit nur einem Dim gegeben hatte Erinnerung an Z80 asm.

Sie können die Huffman-Codierung verwenden, sodass die Zahlen unterschiedliche Bitlängen haben. Wenn Sie sich einer Ziffer bewusst sind, die häufiger als andere vorkommt, ist dies hilfreich.

Beispiel (bei gleicher Häufigkeit):

0 - 1111

1 - 1110

2 - 110

3 - 101

4 - 100

5 - 011

6 - 010

7 - 001

8 - 000

Beispiel für die Empfangsseite, um die Nummer 1 zu erhalten:

Das erste Bit kommt herein und lässt nur 0 bis 4 als Optionen übrig.

das zweite Bit kommt herein und lässt nur 0 bis 2 als Optionen übrig.

das dritte Bit kommt herein und lässt 0 bis 1 als Optionen.

das vierte Bit kommt herein und die eingehende Zahl ist 1

Vielleicht suchen Sie nach arithmetischer Codierung, die eine Reihe von Symbolen effizient codieren kann, von denen jedes im Prinzip eine gebrochene (nicht ganzzahlige) Anzahl von Bits erfordern könnte. (obwohl die gesamte Nachricht eine ganze Anzahl von Bits sein muss)

Wikipedia zitieren :

Die arithmetische Codierung unterscheidet sich von anderen Formen der Entropiecodierung, wie z 1,0).

Die neue IEEE P754 für Fließkommaarithmetik definiert neben binären nun auch dezimale Formate. Eine der Kodierungen schlägt vor, digitale Ziffern um 3 in 10 Bits zu gruppieren.

Die Codierung von 0 bis 999 mit 10 Bits = 1024 möglichen Codes ist ziemlich effizient, und Dezimalziffern werden ohnehin oft zu drei gruppiert.

Dicht gepackte Dezimalzahl : http://en.wikipedia.org/wiki/Densely_packed_decimal

Selbst wenn Dezimalziffern durch drei gruppiert werden, kann eine korrekte Dezimal-Gleitkomma-Semantik erfordern, dass entweder (1) das Skalieren einer Mantisse mit einer Zehnerpotenz, die kein Vielfaches von drei ist, das Multiplizieren oder Dividieren aller Bestandteile mit 10 oder 100 erfordert; (2) einige Bits können entweder für den oberen oder den unteren Teil der Zahl verwendet werden, abhängig von (Exponent mod 3); (3) Wenn der Exponent zur Basis 1000 gespeichert ist, muss die untere Gruppe von drei Ziffern möglicherweise manchmal auf die nächste 10 oder die nächste 100 statt auf die nächste Einheit gerundet werden.
Ich persönlich glaube, dass Typen wie BigDecimalfür viele Zwecke effizienter wären, wenn jedes Wort 9 Dezimalstellen anstelle von 32 Bit enthalten würde, aber das Rundungsverhalten sollte nicht durch die Zifferngruppierung beeinflusst werden.

Eine 1:1-Entsprechung von binär (oder hexadezimal) ist nur eine Symbolcodierung für Bits. Also ja, wie Sie gezeigt haben, ist es möglich. Ein anderer Ort, an dem dies verwendet wird (aber etwas anders), ist die Trellis-Codierung/Decodierung in Kommunikationssystemen, in denen Bitübergänge weiter auseinander gehalten werden, um die Decodierung zu erleichtern. Und natürlich ist die 8b/10b- und 64b/66b-Kodierung usw. eine ähnliche Idee, bei der ein kleinerer Symbolraum in einem etwas redundanten größeren Raum kodiert wird, um DC-Ausgleich, Symboltrennung und Steuercodes in Teilbändern zu erhalten.

Die Datendarstellung hängt von der Interpretation ab, die Sie oder Ihr Programm ihnen geben.

Wir könnten zum Beispiel '27' auch als ASCII-Zeichen senden, was 0x3237 = 0b0011001000110111.

Die Art und Weise, wie Sie die Daten in Bits darstellen möchten, hängt von Ihrer Anwendung ab. Am Ende mit einer Variablen x mit n ( x ) verschiedene mögliche Werte, die Sie brauchen werden Protokoll 2 n ( x ) Bits.

Nehmen wir nun an, Sie haben zwei Variablen x 1 , x 2 mit n ( x 1 ) , n ( x 2 ) mögliche Werte. Wenn Sie sie separat aufbewahren, werden Sie sie brauchen Protokoll 2 n ( x 1 ) + Protokoll 2 n ( x 2 ) Bits. Wenn Sie sie jedoch zusammen aufbewahren, benötigen Sie nur Protokoll 2 ( n ( x 1 ) n ( x 2 ) ) Bits.

In Ihrem Beispiel mit dem Senden von zwei Ziffern können beide Ziffern 10 verschiedene Werte haben. Wenn Sie sie separat aufbewahren, müssen Sie 2 Protokoll 2 ( 10 ) = 2 4 = 8 Bits. Wenn Sie sie jedoch zusammen lagern, brauchen Sie Protokoll 2 ( 10 10 ) = 7 Bits.

Es hängt immer von der Anwendung ab, aber normalerweise kostet es mehr Rechenleistung, wenn Sie Variablen wie von Ihnen vorgeschlagen "verknüpfen", wenn Sie Operationen an diesen Variablen ausführen möchten. Das Addieren und Subtrahieren von Operationen an „verbundenen“ Variablen ist komplexer als normalerweise und kann mehr Platz in der Hardware erfordern oder längere Verzögerungen verursachen.


Notiz: ist die Notation für das Aufrunden .

Die übliche Methode zum Packen von Werten besteht darin, jeden Wert mit seinem Bereich zu multiplizieren, sodass Sie am Ende eine große Zahl erhalten, die Sie effizient in Bits darstellen können. Beim Entpacken dividierst du nach Bereich, der Rest ist die Ziffer, und das Ergebnis sind die verbleibenden gepackten Ziffern.

Wenn Sie 5 Werte im Bereich von 0 bis 2 haben, können Sie dies in 8 Bits darstellen (Sie benötigen mindestens 7,92 Bits, um die Werte darzustellen) anstelle der 10 Bits, die von der naiven Methode verwendet werden, 2 Bits für jeden Wert zu verwenden. durch (((n 1 * 3 + n 2 ) * 3 + n 3 ) * 3 + n 4 ) * 3 + n 5

Gibt es einen Namen für diese Kodierungsmethode?

Wenn Sie bereit sind, Schaltungsplatz und Strom für den hochohmigen Detektor aufzuwenden, können Sie theoretisch 3 Zustände über eine digitale Leitung senden (1, 0 und High-Z). Haftungsausschluss: Dies funktioniert im Simulator hervorragend. Ich weiß nicht, ob die Schaltung einige Probleme hat, die sie unpraktisch machen, wie zum Beispiel, dass sie nicht so schnell schalten kann wie ein normales Gate-Paar.

Mein normaler Begriff für einen Signalübergang von High-Z zu Signal (wobei das Signal normalerweise in Silizium geerdet ist) ist ein Halbbitsignal.

Ich glaube, Sie missverstehen, was in dem verlinkten Wiki-Artikel gemeint ist. Gemeint ist, dass Sie bei einer vollständig numerischen Zeichenfolge (ohne Leerzeichen, Kommas oder Punkte) bei idealer Komprimierung jedes Zeichen mit durchschnittlich 3 1 / 3 Bit darstellen können . Eigentlich ist es ein bisschen besser als das, da die Mathematik sagt, dass Sie auf lange Sicht log 2 (10) = 3,3219 Bits/Zeichen erhalten können.

In ähnlicher Weise benötigen Sie für den Satz alphanumerischer Zeichen plus einige Symbole (nur Großbuchstaben und 9 Symbole) oder 45 Zeichen log 2 (45) = 5,4918 Bits/Zeichen, was im Artikel auf 5,5 aufgerundet wird.

Die reduzierten Bits / Zeichen werden durch Komprimierung erreicht, entweder mit einer voreingestellten Codierung oder einem vom QR-Standard festgelegten Komprimierungsschema (ich bin mir nicht sicher, welches verwendet wird). Es stellt die durchschnittliche Anzahl von Bits dar, die ein Zeichen benötigt, um codiert zu werden, sodass ein einzelnes Zeichen mit mehr oder weniger Bits codiert wird. Beachten Sie auch, dass die oben aufgeführten Werte die idealen Werte für unendliche, zufällige Zeichenfolgen sind. Es ist möglich, Kompressionsverhältnisse zu erzielen, die für speziell gefertigte Saiten besser oder schlechter sind.

Sie möchten eine Dezimalziffer senden, die 3⅓ Bits benötigt. Aber Sie müssen 4 Bits verwenden, da Sie kein Drittel eines Bits senden können.

Um also herauszufinden, was 3⅓ Bits wirklich bedeuten, benötigen Sie zwei (oder drei) Ziffern mit jeweils 3⅓ Bits. Wenn Sie 2 (3) Dezimalziffern zwischen 0 und 9 senden möchten, die jeweils etwas weniger als 3⅓ Bits benötigen, können Sie dies mit 7 (10) Bits tun. Konstruktiver Beweis ist einfach:

Mit 7 (10) Bits können Sie eine Zahl zwischen 0 und 128 (1023) codieren – aber Sie benötigen nur 00 (000) bis 99 (999), was alles mögliche Codierungen von zwei (drei) Dezimalziffern sind. QED