¿Hay alguna forma de usar medios bits?

Como la mayoría de la gente aquí sabe, al usar 4 bits, podemos contar de 0 a 15 (0123456789ABCDEF en hexadecimal). Pero si tuviéramos que contar solo hasta 9, todavía estaríamos usando 4 bits, y los dígitos de la A a la F se desperdiciarían.

Sin embargo, la página de códigos QR de Wikipedia establece que usar solo dígitos numéricos del 0 al 9 usa 3⅓ bits por carácter, lo cual es correcto desde un punto de vista estadístico. Y, sin embargo, un tercio de un bit no es un objeto físico, y enviar un número del 0 al 9 usa al menos 4 bits que yo sepa.

¿Hay alguna forma de usar las combinaciones desperdiciadas para enviar efectivamente un carácter con fracciones de bits?

OK, déjame darte un ejemplo: Los dos dígitos "27" deben ser enviados. Con técnicas de codificación normales, los bits enviados serían 00100111. Entonces podríamos imaginar un sistema que reemplazara el dígito '2' por el dígito 'E' o 'F', dependiendo del siguiente bit; en este caso, el siguiente bit es 0, por lo que el '2' se reemplaza por 'E'. La cadena de bits resultante sería entonces 1101 0 111. Por otro lado, si se deben enviar los dígitos "28", el primer bit después del '2' es un 1, por lo que se reemplaza por el dígito 'F' en su lugar, dando la cadena 1111 1 000.

En ambos casos, se ha realizado una economía de 1 bit, porque se utilizó un nibble para dos caracteres diferentes. En otras palabras, se utilizan tres bits y medio en cada carácter.

Para obtener una perspectiva diferente sobre el empaquetado de valores en un espacio de dígitos más pequeño, consulte las computadoras Ternary ( en.wikipedia.org/wiki/Ternary_computer ) ¡Si es lo suficientemente bueno para Knuth, es lo suficientemente bueno para mí!
Es mejor aún reconocer que puede calcular (10 * first_digit) + second_digity codificar eso en 7 bits, que representan 0...99, con los códigos 100-127 sobrantes para otras cosas. Y hay aún más ahorros con 3 dígitos comprimidos en 10 bits.
Para enviar los 100 valores diferentes por separado, lo mejor que puede obtener es empaquetar en 7 bits. Si tiene más dígitos, el empaquetado será más eficiente. Si tiene menos de 64 valores para enviar, puede enviarlos usando solo 6 bits

Respuestas (10)

No puede enviar medio bit, pero puede empaquetar efectivamente dos medios bits en un bit antes de la transmisión o el almacenamiento.

Usted mismo da un ejemplo, por lo que efectivamente ha respondido su propia pregunta con un SÍ.

Una forma quizás algo más fácil es simplemente codificar el valor de dos dígitos decimales en 7 bits. (Una especie de decimal dual codificado en binario).

Un buen caso de uso para empaquetar pares de dígitos en siete bits es cuando se transmiten archivos ASCII que consisten principalmente en datos numéricos. Cualquier valor de byte por debajo de 128 representa un solo carácter ASCII, mientras que 128-227 representan dos dígitos ASCII. Fácil de codificar o decodificar, y no requiere que los datos contengan principalmente dígitos (o incluso cualquier dígito), pero puede comprimir cadenas de dígitos en un 50 % muy fácilmente.
O ese formato PDP11 que empaquetaba 3 caracteres alfanuméricos en 16 bits con un bit de reserva...
@BrianDrummond: Uno podría usar 16 bits para almacenar exactamente tres caracteres de un conjunto de 40, o hasta tres de un conjunto de 39, pero no habría un bit de repuesto. Normalmente, "alfanumérico" implicaría un conjunto de al menos 36, pero la única forma en que habría un bit de repuesto sería si el conjunto se limitara a 32.
Pensé que era de 5 bits/char. El alfanumérico se dividió en dos conjuntos de códigos, con un símbolo reservado para "conjunto de códigos de conmutación". Me equivoqué: en.wikipedia.org/wiki/DEC_Radix-50 Sin embargo, lo suficientemente raro, solo lo vi una noche cuando tuve que decodificar un informe que alguien me dio en un disquete de 8 ", en un sistema CP / M, con solo un dim recuerdo de Z80 asm.

Puede usar la codificación huffman para que los números tengan una longitud de bits variable. si está al tanto de un dígito que ocurrirá con más frecuencia que otros, será de ayuda.

ejemplo (con igual ocurrencia):

0 - 1111

1 - 1110

2 - 110

3 - 101

4 - 100

5 - 011

6 - 010

7 - 001

8 - 000

Ejemplo de extremo receptor para obtener el número 1:

El primer bit entra y deja solo 0 a 4 como opciones.

el segundo bit entra y deja solo 0 a 2 como opciones.

entra el tercer bit y deja 0 a 1 como opciones.

el cuarto bit entra y el número entrante es 1

Tal vez lo que está buscando es la codificación aritmética, que puede codificar de manera eficiente una cadena de símbolos, cada uno de los cuales, en principio, podría requerir un número fraccionario (no entero) de bits. (aunque el mensaje total debe ser un número entero de bits)

Citando Wikipedia :

La codificación aritmética difiere de otras formas de codificación de entropía, como la codificación de Huffman, en que, en lugar de separar la entrada en símbolos componentes y reemplazar cada uno con un código, la codificación aritmética codifica el mensaje completo en un solo número, una fracción n donde (0.0 ≤ n < 1.0).

El nuevo IEEE P754 para aritmética de coma flotante ahora define formatos decimales además de binarios. Una de las codificaciones propone agrupar los dígitos digitales por 3 en 10 bits.

la codificación de 0 a 999 usando 10 bits = 1024 códigos posibles es bastante eficiente, y los dígitos decimales a menudo se agrupan por tres de todos modos.

Decimal densamente empaquetado : http://en.wikipedia.org/wiki/Densely_packed_decimal

Incluso si los dígitos decimales se agrupan por tres, la semántica correcta de coma flotante decimal puede requerir que (1) escalar una mantisa por una potencia de diez que no sea múltiplo de tres implique multiplicar o dividir todos los constituyentes por 10 o 100; (2) algunos bits se pueden usar para la parte superior o inferior del número, según (exponente mod 3); (3) Si el exponente se almacena en base 1000, entonces el grupo inferior de tres dígitos a veces puede tener que redondearse al 10 más cercano o al 100 más cercano, en lugar de a la unidad más cercana.
Personalmente, creo que los tipos como BigDecimalserían más eficientes para muchos propósitos si cada palabra tuviera 9 dígitos decimales en lugar de 32 bits, pero los comportamientos de redondeo no deberían verse afectados por la agrupación de dígitos.

Una correspondencia 1:1 de binario (o hexadecimal) no es más que una codificación de símbolo para bits. Así que sí, como usted mostró que es posible. Otro lugar en el que esto se usa es (pero de forma ligeramente diferente) en la codificación/descodificación trellis en sistemas de comunicación en los que las transiciones de bits se mantienen más separadas para facilitar la decodificación. Y, por supuesto, la codificación 8b/10b y 64b/66b, etc., etc. es una idea similar, en la que un espacio de símbolo más pequeño se codifica en un espacio más grande ligeramente redundante para obtener equilibrio de CC, separación de símbolo y códigos de control en subbandas.

La representación de datos depende de la interpretación que usted o su programa le den.

Podríamos enviar '27' también como caracteres ASCII, por ejemplo, produciendo 0x3237 = 0b0011001000110111.

La forma en que desea representar los datos en bits depende de su aplicación. Al final, con una variable X con norte ( X ) diferentes valores posibles, vas a necesitar Iniciar sesión 2 norte ( X ) pedacitos

Ahora suponga que tiene dos variables X 1 , X 2 con norte ( X 1 ) , norte ( X 2 ) valores posibles. Si los guarda por separado, necesitará Iniciar sesión 2 norte ( X 1 ) + Iniciar sesión 2 norte ( X 2 ) pedacitos Sin embargo, si los almacena juntos, solo necesitará Iniciar sesión 2 ( norte ( X 1 ) norte ( X 2 ) ) pedacitos

En su ejemplo con el envío de dos dígitos, ambos dígitos pueden tener 10 valores diferentes. Si los almacena por separado, necesita 2 Iniciar sesión 2 ( 10 ) = 2 4 = 8 pedacitos Sin embargo, si los almacena juntos, necesita Iniciar sesión 2 ( 10 10 ) = 7 pedacitos

Siempre depende de la aplicación, pero normalmente cuando 'une' variables como sugiere, costará más potencia de cálculo si desea realizar operaciones en estas variables. Las operaciones de suma y resta en variables 'unidas' son más complejas de lo normal y pueden requerir más espacio en el hardware o causar demoras más prolongadas.


Nota: es la notación para redondear hacia arriba .

La forma habitual de empaquetar valores es multiplicando cada valor por su rango, por lo que termina con un número grande que puede representar eficientemente en bits. Al desempaquetar, divide por rango, el resto es el dígito y el resultado son los dígitos empaquetados restantes.

Si tiene 5 valores en el rango de 0 a 2, puede representar eso en 8 bits (necesita al menos 7,92 bits para representar los valores) en lugar de los 10 bits utilizados por la forma ingenua de usar 2 bits para cada valor, haciendo (((n 1 * 3 + n 2 ) * 3 + n 3 ) * 3 + n 4 ) * 3 + n 5

¿Hay un nombre para este método de codificación?

En teoría, si está dispuesto a gastar espacio en el circuito y energía para el detector de alta impedancia, puede enviar 3 estados por un cable digital (1, 0 y Z alto). Descargo de responsabilidad: esto funciona muy bien en el simulador. No sé si el circuito tiene algunos problemas que lo hacen poco práctico, como decir que realmente no puede cambiar tan rápido como un par de puertas normales.

Mi término normal para una transición de señal de alta Z a señal (donde la señal generalmente está molida en silicio) es una señal de medio bit.

Creo que estás malinterpretando lo que significa el artículo wiki vinculado. Lo que se quiere decir es que para una cadena de caracteres que es completamente numérica (sin espacios, comas o puntos), usando una compresión ideal , puedes representar cada carácter usando 3 1/3 bits en promedio . En realidad, es un poco mejor que esto, ya que las matemáticas dicen que puedes obtener log 2 (10) = 3,3219 bits/carácter a largo plazo.

De manera similar, para el conjunto de caracteres alfanuméricos más algunos (solo mayúsculas y 9 símbolos), o 45 caracteres, necesita log 2 (45) = 5,4918 bits/carácter, que se redondea a 5,5 en el artículo.

Los bits/carácter reducidos se logran mediante compresión, ya sea con una codificación preestablecida o un esquema de compresión especificado por el estándar QR (no estoy seguro de cuál se usa). Representa la cantidad promedio de bits que necesitará un carácter para codificarse, por lo que un carácter individual se codificará utilizando más o menos bits. También tenga en cuenta que los valores enumerados anteriormente son los valores ideales para cadenas aleatorias infinitas. Es posible obtener relaciones de compresión mejores o peores para cuerdas especialmente diseñadas.

Desea enviar un dígito decimal y necesita 3⅓ bits. Pero tendrás que usar 4 bits, porque no puedes enviar un tercio de bit.

Entonces, para saber qué significa realmente 3⅓ bits, necesita dos (o tres) dígitos de 3⅓ bits cada uno. Si desea enviar 2 (3) dígitos decimales entre 0 y 9, cada uno de los cuales necesita un poco menos de 3⅓ bits, puede hacerlo utilizando 7 (10) bits. La prueba constructiva es fácil:

7 (10) bits le permiten codificar un número entre 0 y 128 (1023), pero solo necesitará 00 (000) a 99 (999), que son codificaciones posibles de dos (tres) dígitos decimales. QED