¿Un flotador tiene 32 dígitos binarios y un doble tiene 64 dígitos binarios? La documentación era demasiado difícil de entender.
¿Todos los bits se traducen en dígitos significativos? ¿O la ubicación del punto decimal ocupa algunos de los bits?
¿Un flotador tiene 32 dígitos binarios y un doble tiene 64 dígitos binarios? La documentación era demasiado difícil de entender.
¿Todos los bits se traducen en dígitos significativos? ¿O la ubicación del punto decimal ocupa algunos de los bits?
Respuestas:
flotante : 32 bits (4 bytes) donde se utilizan 23 bits para la mantisa (aproximadamente 7 dígitos decimales). Se utilizan 8 bits para el exponente, por lo que un flotante puede "mover" el punto decimal a la derecha oa la izquierda utilizando esos 8 bits. Si lo hace, evita almacenar muchos ceros en la mantisa, como en 0.0000003 (3 × 10 -7 ) o 3000000 (3 × 10 7 ). Se utiliza 1 bit como bit de signo.
doble : 64 bits (8 bytes) donde se utilizan 52 bits para la mantisa (aproximadamente 16 dígitos decimales). Se utilizan 11 bits para el exponente y 1 bit es el bit de signo.
Dado que estamos usando binario (solo 0 y 1), un bit en la mantisa es implícitamente 1 (tanto float como double usan este truco) cuando el número es distinto de cero.
Además, dado que todo está en binario (mantisa y exponentes), las conversiones a números decimales generalmente no son exactas. Números como 0.5, 0.25, 0.75, 0.125 se almacenan exactamente, pero 0.1 no. Como han dicho otros, si necesita almacenar centavos con precisión, no use float o double, use int, long, BigInteger o BigDecimal.
Fuentes:
http://en.wikipedia.org/wiki/Floating_point#IEEE_754:_floating_point_in_modern_computers
double
y 7.2 para float
, es decir, 15 y 7. Algunos números más grandes se pueden representar en cada caso, y ninguno de ellos se aplica a las fracciones, pero no hay un 'promedio' al respecto, y ninguna de sus fuentes dice de otra manera.
Respuesta larga:
Los números de coma flotante tienen tres componentes:
Esencialmente, esto funciona sign * 2^exponent * (1 + fraction)
. El "tamaño" del número, su exponente, es irrelevante para nosotros, porque solo escala el valor de la fracción. Sabiendo que log₁₀(n)
da el número de dígitos de n
, † podemos determinar la precisión de un número de coma flotante con log₁₀(largest_possible_fraction)
. Debido a que cada bit en un flotante almacena 2 posibilidades, un número binario de n
bits puede almacenar un número hasta 2ⁿ - 1
(un total de 2ⁿ
valores donde uno de los valores es cero). Esto se vuelve un poco más complicado, porque resulta que los números de punto flotante se almacenan con un bit menos de fracción de la que pueden usar, porque los ceros se representan de manera especial y todos los números distintos de cero tienen al menos un bit binario distinto de cero. ‡
Combinando esto, los dígitos de precisión para un número de punto flotante son
log₁₀(2ⁿ)
, donde n
es el número de bits de la fracción del número de punto flotante. Un flotante de 32 bits tiene 24 bits de fracción para ≈7,22 dígitos decimales de precisión, y un doble de 64 bits tiene 53 bits de fracción para ≈15,95 dígitos decimales de precisión.
Para obtener más información sobre la precisión del punto flotante, es posible que desee leer sobre el concepto de una máquina épsilon .
† Por lo n ≥ 1
menos, para otros números, su fórmula se parecerá más
⌊log₁₀(|n|)⌋ + 1
.
‡ "Esta regla se denomina de forma diversa convención de bits inicial, convención de bits implícita o convención de bits ocultos". ( Wikipedia )
De la especificación java :
Los tipos de coma flotante son flotante y doble, que están asociados conceptualmente con los valores y operaciones de formato de precisión simple de 32 bits y de 64 bits de precisión doble IEEE 754, como se especifica en el estándar IEEE para aritmética de coma flotante binaria, ANSI / IEEE Estándar 754-1985 (IEEE, Nueva York).
Como es difícil hacer algo con números sin comprender los conceptos básicos de IEEE754, aquí hay otro enlace .
Es importante comprender que la precisión no es uniforme y que este no es un almacenamiento exacto de los números como se hace para los enteros.
Un ejemplo :
double a = 0.3 - 0.1;
System.out.println(a);
huellas dactilares
0.19999999999999998
Si necesita precisión arbitraria (por ejemplo, con fines financieros), es posible que necesite Big Decimal .
Una respuesta matemática normal.
Entendiendo que un número de punto flotante se implementa como algunos bits que representan el exponente y el resto, la mayoría para los dígitos (en el sistema binario), uno tiene la siguiente situación:
Con un exponente alto, digamos 10²³ si se cambia el bit menos significativo, aparece una gran diferencia entre dos números visibles adyacentes. Además, el punto decimal en base 2 hace que muchos números en base 10 solo se puedan aproximar; 1/5, siendo 1/10 números infinitos.
Entonces, en general : los números de punto flotante no deben usarse si le interesan los dígitos significativos. Para cantidades monetarias con cálculo, e, a, mejor use BigDecimal .
Para la física, los dobles de coma flotante son adecuados, los flotadores casi nunca. Además, la parte de punto flotante de los procesadores, la FPU, puede incluso utilizar un poco más de precisión internamente.
Los números de coma flotante se codifican utilizando una forma exponencial, es m * b ^ e
decir, no como enteros en absoluto. La pregunta que haga sería significativa en el contexto de números de punto fijo . Existen numerosas bibliotecas aritméticas de coma fija disponibles.
Respecto a la aritmética de coma flotante: El número de dígitos decimales depende de la presentación y del sistema numérico. Por ejemplo, hay números periódicos ( 0.33333
) que no tienen una presentación finita en decimal pero sí tienen una en binario y viceversa.
También vale la pena mencionar que los números de coma flotante hasta cierto punto sí tienen una diferencia mayor que uno, es decir , value + 1
rendimientos value
, ya value + 1
que no se pueden codificar usando m * b ^ e
, where m
, b
y e
tienen una longitud fija. Lo mismo ocurre con valores menores a 1, es decir, no todos los puntos de código posibles tienen la misma distancia.
Debido a esto, no hay precisión de n
dígitos exactos como con los números de punto fijo, ya que no todos los números con n
dígitos decimales tienen una codificación IEEE.
Hay un documento casi obligatorio que debería leer entonces y que explica los números de punto flotante: Lo que todo científico informático debería saber sobre la aritmética de punto flotante .
Mire Float.intBitsToFloat
y Double.longBitsToDouble
, que explica cómo los bits se corresponden con los números de punto flotante. En particular, los bits de una normal se float
parecen a
s * 2^exp * 1.ABCDEFGHIJKLMNOPQRSTUVW
donde A ... W son 23 bits - 0 y 1 - que representan una fracción en binario - s es +/- 1, representado por un 0 o un 1 respectivamente, y exp es un entero de 8 bits con signo.