Gran diferencia.
Como su nombre lo indica, a double
tiene 2 veces la precisión de [1] . En general, a tiene 15 dígitos decimales de precisión, mientras que tiene 7.float
double
float
Así se calcula el número de dígitos:
double
tiene 52 bits de mantisa + 1 bit oculto: log (2 53 ) ÷ log (10) = 15.95 dígitos
float
tiene 23 bits de mantisa + 1 bit oculto: log (2 24 ) ÷ log (10) = 7.22 dígitos
Esta pérdida de precisión podría conducir a la acumulación de errores de truncamiento mayores cuando se realizan cálculos repetidos, por ej.
float a = 1.f / 81;
float b = 0;
for (int i = 0; i < 729; ++ i)
b += a;
printf("%.7g\n", b); // prints 9.000023
mientras
double a = 1.0 / 81;
double b = 0;
for (int i = 0; i < 729; ++ i)
b += a;
printf("%.15g\n", b); // prints 8.99999999999996
Además, el valor máximo de flotante es aproximadamente 3e38
, pero el doble es aproximadamente 1.7e308
, por lo que usar float
puede alcanzar el "infinito" (es decir, un número especial de coma flotante) mucho más fácilmente que double
para algo simple, por ejemplo, calcular el factorial de 60.
Durante las pruebas, tal vez algunos casos de prueba contengan estos números enormes, lo que puede hacer que sus programas fallen si usa flotadores.
Por supuesto, a veces, incluso double
no es lo suficientemente preciso, por lo tanto, a veces tenemos long double
[1] (el ejemplo anterior da 9.000000000000000066 en Mac), pero todos los tipos de coma flotante sufren errores de redondeo , por lo que si la precisión es muy importante (por ejemplo, dinero procesamiento) debe usar int
o una clase de fracción.
Además, no utilice +=
para sumar muchos números de coma flotante, ya que los errores se acumulan rápidamente. Si estás usando Python, úsalo fsum
. De lo contrario, intente implementar el algoritmo de suma Kahan .
[1]: Los estándares C y C ++ no especifican la representación de float
, double
y long double
. Es posible que los tres se implementen como IEEE de doble precisión. Sin embargo, para la mayoría de las arquitecturas (gcc, MSVC; x86, x64, ARM) float
es de hecho un número de coma flotante de precisión simple IEEE (binary32), y double
es un número de coma flotante de precisión doble IEEE (binary64).
Esto es lo que dicen las normas estándar C99 (ISO-IEC 9899 6.2.5 §10) o C ++ 2003 (ISO-IEC 14882-2003 3.1.9 §8):
El estándar C ++ agrega:
Sugeriría echar un vistazo a lo excelente que todo informático debe saber sobre la aritmética de punto flotante que cubre en profundidad el estándar de punto flotante IEEE. Aprenderá sobre los detalles de la representación y se dará cuenta de que existe una compensación entre magnitud y precisión. La precisión de la representación de coma flotante aumenta a medida que disminuye la magnitud, por lo tanto, los números de coma flotante entre -1 y 1 son los que tienen más precisión.
fuente
Dada una ecuación cuadrática: x 2 - 4.0000000 x + 3.9999999 = 0, las raíces exactas a 10 dígitos significativos son, r 1 = 2.000316228 y r 2 = 1.999683772.
Usando
float
ydouble
, podemos escribir un programa de prueba:Ejecutar el programa me da:
Tenga en cuenta que los números no son grandes, pero aún así obtiene efectos de cancelación utilizando
float
.(De hecho, lo anterior no es la mejor manera de resolver ecuaciones cuadráticas utilizando números de coma flotante de precisión simple o doble, pero la respuesta permanece sin cambios incluso si se usa un método más estable ).
fuente
fuente
El tamaño de los números involucrados en los cálculos de coma flotante no es lo más relevante. Es el cálculo que se realiza lo que es relevante.
En esencia, si está realizando un cálculo y el resultado es un número irracional o un decimal recurrente, entonces habrá errores de redondeo cuando ese número se aplaste en la estructura de datos de tamaño finito que está utilizando. Como el doble es dos veces el tamaño del flotador, el error de redondeo será mucho menor.
Las pruebas pueden usar específicamente números que causarían este tipo de error y, por lo tanto, probaron que usaste el tipo apropiado en tu código.
fuente
El tipo flotante, de 32 bits de largo, tiene una precisión de 7 dígitos. Si bien puede almacenar valores con un rango muy grande o muy pequeño (+/- 3.4 * 10 ^ 38 o * 10 ^ -38), solo tiene 7 dígitos significativos.
Tipo doble, 64 bits de largo, tiene un rango mayor (* 10 ^ + / - 308) y precisión de 15 dígitos.
El tipo long double es nominalmente 80 bits, aunque un compilador / sistema operativo determinado puede almacenarlo como 12-16 bytes para fines de alineación. El doble largo tiene un exponente que es ridículamente enorme y debe tener una precisión de 19 dígitos. Microsoft, en su sabiduría infinita, limita el doble largo a 8 bytes, lo mismo que el doble simple.
En términos generales, solo use type double cuando necesite un valor / variable de coma flotante. Los valores literales de coma flotante utilizados en las expresiones se tratarán como dobles por defecto, y la mayoría de las funciones matemáticas que devuelven valores de coma flotante devuelven dobles. Se ahorrará muchos dolores de cabeza y encasillados si solo usa el doble.
fuente
Me topé con un error que me llevó una eternidad descubrir y potencialmente puede darle un buen ejemplo de precisión de flotación.
La salida es
Como puede ver después de 0.83, la precisión se reduce significativamente.
Sin embargo, si configuro
t
como doble, tal problema no sucederá.Me tomó cinco horas darme cuenta de este pequeño error, que arruinó mi programa.
fuente
double
no es una buena solución aquí. Suelesint
contar y hacer una multiplicación interna para obtener tu valor de coma flotante.Los flotadores tienen menos precisión que los dobles. Aunque ya lo sabe, lea Lo que NOSOTROS deberíamos saber sobre la aritmética de coma flotante para una mejor comprensión.
fuente
Cuando utilice números de coma flotante, no puede confiar en que sus pruebas locales serán exactamente las mismas que las pruebas que se realizan en el lado del servidor. El entorno y el compilador son probablemente diferentes en su sistema local y donde se ejecutan las pruebas finales. He visto este problema muchas veces antes en algunas competiciones de TopCoder, especialmente si intentas comparar dos números de coma flotante.
fuente
Las operaciones de comparación incorporadas difieren, ya que cuando compara 2 números con coma flotante, la diferencia en el tipo de datos (es decir, flotante o doble) puede dar lugar a resultados diferentes.
fuente
Si se trabaja con procesamiento incorporado, eventualmente el hardware subyacente (por ejemplo, FPGA o algún modelo específico de procesador / microcontrolador) se implementará flotantemente de manera óptima en el hardware, mientras que el doble utilizará rutinas de software. Entonces, si la precisión de un flotante es suficiente para manejar las necesidades, el programa se ejecutará algunas veces más rápido con flotante y luego doble. Como se señaló en otras respuestas, tenga cuidado con los errores de acumulación.
fuente
A diferencia de un
int
(número entero), afloat
tiene un punto decimal, y también puede adouble
. Pero la diferencia entre los dos es que adouble
es dos veces más detallado que afloat
, lo que significa que puede tener el doble de números después del punto decimal.fuente