2012-08-25 25 views
18

He leído mucho sobre carrozas, pero todo está innecesariamente involucrado. Yo creo lo tengo más o menos conocidos, pero sólo hay una cosa que me gustaría saber con certeza:¿Qué tipos de números son representables en coma flotante binario?

Sé que, fracciones de la forma 1/pow(2,n), con n un número entero, se pueden representar con exactitud en números de coma flotante. Esto significa que si agrego 1/32 a sí mismo 32 millones de veces, obtendría exactamente 1,000,000.

¿Qué tal algo como 1/(32+16)? Es uno sobre la suma de dos poderes de dos, ¿funciona esto? ¿O es 1/32+1/16 que funciona? Aquí es donde estoy confundido, así que si alguien pudiera aclarar eso, lo apreciaría.

Respuesta

27

La regla puede resumirse en lo siguiente:

  • Un número se puede representar exactamente en binario si la descomposición en factores primos del denominador contiene sólo 2. (es decir, el denominador es una potencia de dos hijos)

Así que 1/(32 + 16) no se puede representar en binario porque tiene un factor de 3 en el denominador. Pero 1/32 + 1/16 = 3/32 es.

Dicho esto, hay más restricciones que se pueden representar en un tipo de coma flotante. Por ejemplo, solo tiene 53 bits de mantisa en un IEEE double, por lo que 1/2 + 1/2^500 no es representable.

Así que puedes hacer la suma de poderes-de-dos, siempre y cuando el rango de los exponentes no abarque más de 53 poderes.


Para generalizar esto a otras bases:

  • Un número se puede representar exactamente en la base 10 si la descomposición en factores primos del denominador consiste solamente de 2 y 5 de.

  • un número racional X se puede representar exactamente en la base N si la descomposición en factores primos del denominador de X contiene sólo números primos que se encuentran en la factorización de N.

+3

Entonces, si tengo ese derecho, puedo usar cualquier número 'X/Y' siempre que' Y' sea una potencia de 2 y 'X' sea un número menor que' 2^53'? –

+2

Sí, eso es correcto. (salvo casos de over/underflow) – Mysticial

+0

@Mysticial: +1 por la respuesta, pero tengo una duda. 24/48 = 0.5, sin embargo por la regla anterior, no debe ser representable, ya que 3 es uno de los factores primos de 48, que no es uno de los 10 factores primos. ¿Por qué? – legends2k

4

números de coma flotante son, literalmente, representan usando la forma:

1.m * 2^e 

Dónde 1.m es una fracción binaria y e es un número entero positivo o negativo.

Como tal, puede representar exactamente 1/32 + 1/16, como: (. 1.10 siendo la fracción binaria equivalente a 1,5)

1.1000000 * 2^-4 

1/48, sin embargo, no se puede representar en este formato.

+0

(creo que te refieres a '1.m * 2^e'.) – huon

+0

Derp. Sí, por supuesto. :) – duskwuff

+0

¿No debería ser '1.1000000 * 2^-4'? – mkeiser

0

Un punto aún no mencionado es que, semánticamente, un número de coma flotante puede considerarse mejor que representa un rango de valores.El rango de valores tiene un punto central definido con precisión, y la especificación IEEE generalmente requiere que el resultado de un cálculo en coma flotante sea el número cuyo rango contenga el punto en que uno operará sobre los puntos centrales de los números originales, pero en la secuencia:

 
    double N1 = 0.1; 
    float N2 = (float)N1; 
    double N3 = N2; 

N2 es la representación de precisión simple correcta inequívoca del valor que había sido representado en N1, a pesar requisito tonta de la lengua a utilizar una conversión explícita. N3 representará uno de los valores que N2 podría representar (la especificación de idioma elige el valor double cuyo rango se centra en el medio del rango float). Tenga en cuenta que aunque N2 representa el valor de su tipo cuyo rango contiene el valor correcto, N3 no lo hace.

Por cierto, la conversión de un número de una cadena a un flotante en los lenguajes .net y .net parece pasar por una conversión intermedia a double, que en ocasiones puede alterar el valor. Por ejemplo, aunque el valor 13571357 es representable como un valor flotante de precisión simple, el valor 13571357.499999999069f se redondea a 13571358 (aunque obviamente está más cerca de 13571357).

+0

1. "requisito idiota del lenguaje para usar un elenco explícito": ¿De qué idioma estás hablando? C no requiere un molde aquí ... – glglgl

+0

@glglgl: El código de ejemplo citado sería válido en C, Java o C#; los dos últimos idiomas requieren que el elenco 'flote ', aunque no' doble'. – supercat

+0

Ok, gracias. El comentario 2. ya no se aplica, pensé en la cadena -> doble -> conversión flotante, y parece que estás aquí mismo. – glglgl

8

un número finito se puede representar en el IEEE 754 formato común de doble precisión si y sólo si es igual a M • 2 e para algunos números enteros y M e tal que -2 < M y -1074 ≤ e ≤ 971.

Para precisión simple, -2 < M y -149 ≤ e ≤ 104.

Para la precisión doble, estas son consecuencias de los hechos de que el formato de doble precisión utiliza 52 bits para almacenar un significado (que normalmente tiene 53 bits debido a un 1 implícito) y usa 11 bits para almacenar un exponente. 11 bits codifica números de 0 a 2047, pero 0 y 2047 se excluyen para fines especiales, y el número codificado está sesgado por 1023, por lo que representa exponentes imparciales de -1022 a 1023. Sin embargo, estos exponentes imparciales son para significands en el intervalo [1, 2), y esos significandos tienen fracciones. Para expresar el significado como un entero, ajusté el rango del exponente por 52. La precisión simple es similar, con 23 bits para almacenar un significado de 24 bits, 8 bits para el exponente y un sesgo de 127.

Expresando los números representables que usan un número entero multiplicado por una potencia de dos en lugar del significado fraccionario más común y simplifica la teoría de algunos números y otros razonamientos sobre las propiedades de coma flotante. Lo utilicé en esta respuesta porque permite que el conjunto de valores representables se exprese de manera concisa.

+0

Ver este es exactamente el tipo de "implicación demasiado profunda" que mencioné en mi pregunta ... –

+2

@Kolink: la respuesta en sí es una oración única que indica exactamente qué números pueden y no pueden representarse, usando solo los conceptos familiares de números enteros , multiplicación, poderes y menor que (o igual a). ¿Cuánto más simple que eso puedes obtener? Tienes un número entero multiplicado por dos, y el número entero y el poder tienen que estar dentro de ciertos límites. El resto de la respuesta es solo una explicación sobre de dónde viene la oración. –

+1

+1. Editado para corregir los límites superiores para e. –

Cuestiones relacionadas