binary - simple - sistema binario matematicas
¿Es la precisión más significativa de los dígitos decimales que se puede convertir a binario y volver a decimal sin pérdida de importancia 6 o 7,225? (3)
Estos están hablando de dos cosas ligeramente diferentes.
Los 7.225 1 dígitos son la precisión con la que se puede almacenar un número internamente . Por ejemplo, si hiciste un cálculo con un número de precisión doble (por lo que comenzaste con algo así como 15 dígitos de precisión), luego lo redondeaste a un único número de precisión, la precisión que tendrías en ese punto sería aproximadamente 7 dígitos
Los 6 dígitos hablan de la precisión que se puede mantener mediante una conversión de ida y vuelta desde una cadena de dígitos decimales, a un número de coma flotante y luego a otra serie de dígitos decimales.
Entonces, supongamos que empiezo con un número como 1.23456789
como una cadena, luego lo convierto en un float32, luego convierto el resultado a una cadena. Cuando haya hecho esto, puedo esperar que 6 dígitos coincidan exactamente. Sin embargo, el séptimo dígito puede ser redondeado, por lo que no puedo esperar necesariamente que coincida (aunque probablemente será +/- 1 de la cadena original.
Por ejemplo, considere el siguiente código:
#include <iostream>
#include <iomanip>
int main() {
double init = 987.23456789;
for (int i = 0; i < 100; i++) {
float f = init + i / 100.0;
std::cout << std::setprecision(10) << std::setw(20) << f;
}
}
Esto produce una tabla como la siguiente:
987.2345581 987.2445679 987.2545776 987.2645874
987.2745972 987.2845459 987.2945557 987.3045654
987.3145752 987.324585 987.3345947 987.3445435
987.3545532 987.364563 987.3745728 987.3845825
987.3945923 987.404541 987.4145508 987.4245605
987.4345703 987.4445801 987.4545898 987.4645386
987.4745483 987.4845581 987.4945679 987.5045776
987.5145874 987.5245972 987.5345459 987.5445557
987.5545654 987.5645752 987.574585 987.5845947
987.5945435 987.6045532 987.614563 987.6245728
987.6345825 987.6445923 987.654541 987.6645508
987.6745605 987.6845703 987.6945801 987.7045898
987.7145386 987.7245483 987.7345581 987.7445679
987.7545776 987.7645874 987.7745972 987.7845459
987.7945557 987.8045654 987.8145752 987.824585
987.8345947 987.8445435 987.8545532 987.864563
987.8745728 987.8845825 987.8945923 987.904541
987.9145508 987.9245605 987.9345703 987.9445801
987.9545898 987.9645386 987.9745483 987.9845581
987.9945679 988.0045776 988.0145874 988.0245972
988.0345459 988.0445557 988.0545654 988.0645752
988.074585 988.0845947 988.0945435 988.1045532
988.114563 988.1245728 988.1345825 988.1445923
988.154541 988.1645508 988.1745605 988.1845703
988.1945801 988.2045898 988.2145386 988.2245483
Si miramos a través de esto, podemos ver que los primeros seis dígitos significativos siempre siguen el patrón con precisión (es decir, cada resultado es exactamente 0.01 mayor que su predecesor). Como podemos ver en el double
original, el valor es en realidad 98x.xx456, pero cuando convertimos el flotador de precisión simple a decimal, podemos ver que el séptimo dígito con frecuencia no se leería correctamente, ya que el el dígito subsiguiente es mayor que 5, debe redondear hasta 98x.xx46, pero algunos de los valores no (por ejemplo, el penúltimo elemento en la primera columna es 988.154541
, que sería redondeado hacia abajo en lugar de hacia arriba, por lo tanto terminaríamos con 98x.xx45 en lugar de 46
Por lo tanto, aunque el valor (tal como está almacenado) es de 7 dígitos (más un poco), para el momento en que realicemos un viaje de ida y vuelta del valor a través de una conversión a decimal y viceversa , no podemos depender de que ese séptimo dígito coincida exactamente más (aunque hay suficiente precisión que lo hará con mucha frecuencia).
1. Eso significa básicamente 7 dígitos, y el 8º dígito será un poco más preciso que nada, pero no mucho; por ejemplo, si estuviéramos convirtiendo desde un doble de 1.2345678
, los dígitos de precisión de .225
significan que el último dígito sería con aproximadamente +/- .775 de lo que comenzó allí (mientras que sin los dígitos de precisión de .225
, sería básicamente +/- 1 de lo que comenzó allí).
He encontrado dos fórmulas de precisión diferentes para números de coma flotante.
⌊ (N-1) log 10 (2) ⌋ = 6 dígitos decimales (precisión única)
y
N log 10 (2) ≈ 7.225 dígitos decimales (precisión única)
Donde N = 24 bits significativos (precisión única)
La primera fórmula se encuentra en la parte superior de la página 4 de " IEEE Standard 754 for Binary Floating-Point Arithmetic " escrita por el Profesor W. Kahan .
La segunda fórmula se encuentra en el artículo de Wikipedia " Formato de coma flotante de precisión simple " en la sección IEEE 754 formato binario de coma flotante de precisión simple: binary32 .
Para la primera fórmula, el profesor W. Kahan dice
Si una cadena decimal con un máximo de 6 sig. dic. se convierte a Single y luego se convierte de nuevo al mismo número de sig. dec., entonces la secuencia final debe coincidir con el original.
Para la segunda fórmula, Wikipedia dice
... la precisión total es de 24 bits (equivalente a log 10 (2 24 ) ≈ 7.225 dígitos decimales ).
Los resultados de ambas fórmulas (6 y 7.225 dígitos decimales) son diferentes, y esperaba que fueran los mismos porque asumí que los dos estaban destinados a representar los dígitos decimales más significativos que se pueden convertir a binario de coma flotante y luego se pueden volver a convertir a decimal con el mismo número de dígitos decimales significativos con los que comenzó.
¿Por qué estos dos números son diferentes y cuál es la precisión más significativa de los dígitos decimales que se puede convertir a binario y volver a decimal sin pérdida de importancia?
Tenga en cuenta que son exactamente las mismas fórmulas. Recuerde su identidad de libro de matemáticas de la escuela secundaria:
Log(x^y) == y * Log(x)
Ayuda a calcular realmente los valores para N = 24 con su calculadora:
Kahan''s: 23 * Log(2) = 6.924
Wikipedia''s: Log(2^24) = 7.225
Kahan se vio forzado a truncar 6.924 con 6 dígitos debido al piso (), fastidio. La única diferencia real es que Kahan usó 1 menos de precisión.
Bastante difícil de adivinar por qué, el profesor podría haber confiado en notas antiguas. Escrito antes de IEEE-754 y sin tener en cuenta que el 24º bit de precisión es gratis. El formato utiliza un truco, el bit más significativo de un valor de punto flotante que no es 0 es siempre 1. Por lo tanto, no es necesario almacenarlo. El procesador lo vuelve a agregar antes de realizar un cálculo. Convertir 23 bits de precisión almacenada en 24 de precisión efectiva.
O tuvo en cuenta que la conversión de una cadena decimal a un valor de punto flotante binario genera un error. Muchos buenos valores decimales redondos, como 0.1, no se pueden convertir perfectamente a binarios. Tiene un número infinito de dígitos, al igual que 1/3 en decimal. Sin embargo, eso genera un resultado que está desactivado en +/- 0.5 bits, logrado por simple redondeo. Entonces el resultado es exacto a 23.5 * Log (2) = 7.074 dígitos decimales. Si supuso que la rutina de conversión es torpe y no redondea adecuadamente, el resultado puede estar desactivado en +/- 1 bit y N-1 es apropiado. Ellos no son torpes.
O pensó como un científico típico o (el cielo no lo quiera) contable y quiere que el resultado de un cálculo se convierta nuevamente en decimal. Tal como obtendría cuando busque trivialmente un número decimal de 7 dígitos cuya conversión de ida y vuelta no produzca el mismo número. Sí, eso agrega otro error de +/- 0.5 bit, sumando hasta un total de error de 1 bit.
Pero nunca, nunca cometas ese error, siempre debes incluir los errores que obtienes al manipular el número en un cálculo. Algunos de ellos pierden dígitos significativos muy rápidamente, la sustracción en particular es muy peligrosa.
¿Cuál es la precisión más significativa de los dígitos decimales que se puede convertir en binario y volver a decimal sin pérdida de importancia?
La precisión más significativa de los dígitos decimales que se puede convertir en binario y volver a decimal sin pérdida de significado (para números de coma flotante de precisión simple o 24 bits) es de 6 dígitos decimales.
¿Por qué estos dos números difieren?
Los números 6 y 7.225 difieren, porque definen dos cosas diferentes. 6 es la mayoría de los dígitos decimales que se pueden disparar en redondo. 7.225 es el número aproximado de precisión de dígitos decimales para un entero binario de 24 bits porque un entero binario de 24 bits puede tener 7 u 8 dígitos decimales dependiendo de su valor específico.
7.225 se encontró usando la fórmula entera binaria específica.
d spec = b · log 10 (2) ( especificación d = dígitos decimales específicos, b = bits)
Sin embargo, lo que normalmente necesita saber son los dígitos decimales mínimo y máximo para un entero de b-bit. Las siguientes fórmulas se utilizan para encontrar los dígitos decimales mínimo y máximo (7 y 8 respectivamente para 24 bits) de un entero binario específico.
d min = ⌈ (b-1) · log 10 (2) ⌉ (d min = dígitos decimales mínimos, b = bits, ⌈x⌉ = mínimo entero ≥ x)
d max = ⌈b · log 10 (2) ⌉ (d max = dígitos decimales máximos, b = bits, ⌈x⌉ = d entero más pequeño ≥ x)
Para obtener más información acerca de cómo se derivan estas fórmulas, lea Número de dígitos decimales en un entero binario , escrito por Rick Regan.
Esto está muy bien, pero puede preguntar, ¿por qué es 6 la mayoría de los dígitos decimales para una conversión de ida y vuelta si dice que el lapso de dígitos decimales para un número de 24 bits es de 7 a 8?
La respuesta es ¡porque las fórmulas anteriores solo funcionan para enteros y no para números de coma flotante!
Cada entero decimal tiene un valor exacto en binario. Sin embargo, no puede decirse lo mismo para cada número decimal de coma flotante. Tome .1
por ejemplo. .1
en binario es el número 0.000110011001100...
, que es un binario repetitivo o recurrente. Esto puede producir un error de redondeo.
Además, se necesita un bit más para representar un número de coma flotante decimal que para representar un número entero decimal de igual importancia. Esto se debe a que los números de coma flotante son más precisos cuanto más cerca están de 0 y menos precisos cuanto más lejos están de 0. Debido a esto, muchos números de coma flotante se encuentran cerca de los rangos de valores mínimo y máximo (e min = -126 y e max = +127 para precisión simple) pierde 1 bit de precisión debido a un error de redondeo. Para ver esto visualmente, mira lo que todo programador de computadoras debe saber sobre punto flotante, parte 1 , escrito por Josh Haberman.
Además, hay al menos 784,757
números decimales positivos de siete dígitos que no pueden retener su valor original después de una conversión de ida y vuelta. Un ejemplo de tal número que no puede sobrevivir al viaje de ida y vuelta es 8.589973e9
. Este es el número positivo más pequeño que no conserva su valor original.
Aquí está la fórmula que debería usar para la precisión del número de coma flotante que le dará 6 dígitos decimales para la conversión de ida y vuelta.
d max = ⌊ (b-1) · log 10 (2) ⌋ (d max = dígitos decimales máximos, b = bits, ⌊x⌋ = mayor entero ≤ x)
Para obtener más información acerca de cómo se deriva esta fórmula, lea Número de dígitos necesarios para las conversiones de ida y vuelta , también escrito por Rick Regan. Rick hace un excelente trabajo mostrando la derivación de fórmulas con referencias a pruebas rigurosas.
Como resultado, puede utilizar las fórmulas anteriores de una manera constructiva; Si comprende cómo funcionan, puede aplicarlos a cualquier lenguaje de programación que use tipos de datos de coma flotante. Todo lo que debe saber es la cantidad de bits significativos que tiene su tipo de datos de punto flotante, y puede encontrar su número respectivo de dígitos decimales con los que puede contar para no perder importancia después de una conversión de ida y vuelta.
Actualización del 18 de junio de 2017: Deseo incluir un enlace al nuevo artículo de Rick Regan, que entra en más detalles y, en mi opinión, responde mejor esta pregunta que cualquier respuesta proporcionada aquí. Su artículo es " Precisión decimal de números binarios de coma flotante " y se puede encontrar en su sitio web www.exploringbinary.com .