que - textarea java jframe
¿Cuántos dígitos significativos tienen flotantes y dobles en Java? (6)
¿Tiene un flotante 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 de 32 bits tiene aproximadamente 7 dígitos de precisión y un doble de 64 bits tiene alrededor de 16 dígitos de precisión
Respuesta larga:
Los números de coma flotante tienen tres componentes:
- Un signo de bit, para determinar si el número es positivo o negativo.
- Un exponente, para determinar la magnitud del número.
- Una fracción, que determina qué tan lejos está entre dos valores de exponente el número. Esto a veces se llama "el significando, mantisa o coeficiente"
Básicamente, esto funciona para sign * 2^exponent * (1 + fraction)
. El "tamaño" del número, su exponente, es irrelevante para nosotros, ya que solo escala el valor de la porción de fracción. Sabiendo que log₁₀(n)
da la cantidad de dígitos de n
, † podemos determinar la precisión de un número de coma flotante con log₁₀(largest_possible_fraction)
. Como cada bit en un flotante almacena 2 posibilidades, un número binario de n
bits puede almacenar un número de hasta 2ⁿ - 1
(un total de 2ⁿ
valores donde uno de los valores es cero). Esto se pone un poco más peludo, porque resulta que los números de coma flotante se almacenan con un fragmento menos de fracción del que pueden usar, porque los ceros están representados especialmente 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 coma flotante son log₁₀(2ⁿ)
, donde n
es el número de bits de la fracción del número de coma flotante. Un flotador de 32 bits tiene 24 bits de fracción para decimal7.22 dígitos decimales de precisión, y un doble de 64 bits tiene 53 bits de fracción para decimal15.95 dígitos decimales de precisión.
Para obtener más información sobre la precisión de punto flotante, es posible que desee leer sobre el concepto de un épsilon de máquina .
† Para n ≥ 1
como mínimo, para otros números, su fórmula se parecerá más a ⌊log₁₀(|n|)⌋ + 1
.
‡ "Esta regla se conoce como la convención de bits líder, la convención de bits implícita o la convención de bits ocultos." ( Wikipedia )
De la especificación de java :
Los tipos de punto flotante son float y double, que se asocian conceptualmente con los valores de IEEE 754 y de formato de 64 bits de precisión simple de 32 bits y doble precisión, como se especifica en el estándar IEEE para Aritmética de punto flotante binario, ANSI / IEEE Estándar 754-1985 (IEEE, Nueva York).
Como es difícil hacer cualquier cosa con los números sin entender los conceptos básicos de IEEE754, aquí hay otro enlace .
Es importante entender 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 una precisión arbitraria (por ejemplo, para fines financieros), puede necesitar Big Decimal .
Los números flotantes se codifican usando una forma exponencial, que es algo así como m * b ^ e
, es decir, no como enteros en absoluto. La pregunta que haga será significativa en el contexto de los números de puntos fijos . Hay numerosas bibliotecas aritméticas de punto fijo disponibles.
Con respecto a la aritmética de punto 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 un cierto punto tienen una diferencia mayor que uno, es decir, el value + 1
arroja value
, ya que el value + 1
no puede codificarse usando m * b ^ e
, donde m
, e
son fijos en longitud. Lo mismo ocurre con valores inferiores a 1, es decir, todos los posibles puntos de código no tienen la misma distancia.
Debido a esto, no hay precisión de exactamente n
dígitos, 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ías leer y que explica los números en coma flotante: Lo que todo científico de la computación debería saber sobre la aritmética de coma flotante .
Mire Float.intBitsToFloat
y Double.longBitsToDouble
, que explican cómo los bits se corresponden con los números de coma flotante. En particular, los bits de un float
normal se ven algo así como
s * 2^exp * 1.ABCDEFGHIJKLMNOPQRSTUVW
donde A ... W son 23 bits - 0s y 1s - representa 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.
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 alto exponente, digamos 10²³ si se cambia el bit menos significativo, aparece una gran diferencia entre dos números distinguibles adyacentes. Además, el punto decimal base 2 hace que muchos números base 10 solo puedan ser aproximados; 1/5, 1/10 son números interminables.
Por lo tanto, en general : los números de coma flotante no deben usarse si le importan los dígitos significativos. Para montos monetarios con cálculo, e, a, mejor uso BigDecimal .
Para física, los dobles de coma flotante son adecuados, flota casi nunca. Además, la parte de coma flotante de los procesadores, la FPU, incluso puede usar un poco más de precisión internamente.
float : 32 bits (4 bytes) donde se usan 23 bits para la mantisa (alrededor de 7 dígitos decimales). Se usan 8 bits para el exponente, por lo que un flotador puede "mover" el punto decimal hacia la derecha o hacia la izquierda utilizando esos 8 bits. Hacerlo evita almacenar muchos ceros en la mantisa como en 0.0000003 (3 × 10 -7 ) o 3000000 (3 × 10 7 ). Hay 1 bit utilizado como bit de signo.
double : 64 bits (8 bytes) donde se usan 52 bits para la mantisa (alrededor de 16 dígitos decimales). Se usan 11 bits para el exponente y 1 bit es el bit de signo.
Dado que estamos usando binarios (solo 0 y 1), un bit en la mantisa es implícitamente 1 (tanto float como double usan este truco) cuando el número no es cero.
Además, como todo está en binario (mantisa y exponentes), las conversiones a números decimales generalmente no son exactas. Los 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, utilice int, long, BigInteger o BigDecimal.
Fuentes:
http://en.wikipedia.org/wiki/Floating_point#IEEE_754:_floating_point_in_modern_computers