El error de la Calculadora de Google podría flotar vs.¿El doble es una posible razón?

StackOverflow https://stackoverflow.com/questions/27095

  •  09-06-2019
  •  | 
  •  

Pregunta

Hice esto solo por diversión (así que no es exactamente una pregunta, puedo ver que la modificación ya está ocurriendo) pero, en lugar de la nueva función de Google incapacidad hacer matemáticas correctamente (¡revisalo!según Google 500.000.000.000.002 - 500.000.000.000.001 = 0), pensé en probar lo siguiente en C para ejecutar un poco de teoría.

int main()
{
   char* a = "399999999999999";
   char* b = "399999999999998";

   float da = atof(a);
   float db = atof(b);

   printf("%s - %s = %f\n", a, b, da-db);

   a = "500000000000002";
   b = "500000000000001";
   da = atof(a);
   db = atof(b);
   printf("%s - %s = %f\n", a, b, da-db);
}

Cuando ejecuta este programa, obtiene lo siguiente

   399999999999999 - 399999999999998 = 0.000000
   500000000000002 - 500000000000001 = 0.000000

Parecería que Google está usando precisión flotante simple de 32 bits (el error aquí), si cambia float por double en el código anterior, ¡solucionará el problema!¿Podría ser esto?

/mp

¿Fue útil?

Solución

en C#, prueba (double.maxvalue == (double.maxvalue - 100)), obtendrás verdadero...

pero eso es lo que se supone que es:

http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems

pensándolo bien, tiene 64 bits que representan un número mayor que 2 ^ 64 (doble valor máximo), por lo que se espera inexactitud.

Otros consejos

Para más información sobre este tipo de tonterías, consulte este bonito artículo sobre la calculadora de Windows.

Cuando cambias el interior, nadie se da cuenta.

Las entrañas de Calc, el motor aritmético, fueron completamente tirados y reescritos desde cero.La biblioteca estándar de puntos flotantes IEEE fue reemplazada por una biblioteca aritmética de precisión arbitraria.Esto se hizo después de que las personas seguían escribiendo artículos de Ha -Ha sobre cómo Calc no podía hacer la aritmética decimal correctamente, que, por ejemplo, calcular 10.21 - 10.2 resultó en 0.010000000000000016.

Parecería que Google está usando precisión flotante simple de 32 bits (el error aquí), si cambia float por double en el código anterior, ¡solucionará el problema!¿Podría ser esto?

No, simplemente postergues el asunto.los dobles todavía presentan el mismo problema, solo que con números mayores.

@ebel

pensándolo bien, tiene 64 bits que representan un número mayor que 2 ^ 64 (doble valor máximo), por lo que se espera inexactitud.

2^64 no es el valor máximo de un doble.2^64 es el número de valores únicos que puede contener un doble (o cualquier otro tipo de 64 bits). Double.MaxValue es igual a 1.79769313486232e308.

La inexactitud con los números de punto flotante no proviene de representar valores mayores que Double.MaxValue (lo cual es imposible, excluyendo Double.PositiveInfinity).Proviene del hecho de que el rango de valores deseado es simplemente demasiado grande para caber en el tipo de datos.Por eso renunciamos a la precisión a cambio de un alcance efectivo mayor.En esencia, estamos eliminando dígitos significativos a cambio de un rango de exponentes mayor.

@DrPizza

Ni siquiera;las codificaciones IEEE utilizan múltiples codificaciones para los mismos valores.Específicamente, NaN está representado por un exponente de todos los bits-1 y luego cualquier valor distinto de cero para la mantisa.Como tal, hay 252 NaN para dobles y 223 NaN para individuales.

Verdadero.No tuve en cuenta codificaciones duplicadas.En realidad hay 252-1 NaNs para dobles y 223-1 NaN para solteros, sin embargo.:pag

2^64 no es el valor máximo de un doble.2^64 es el número de valores únicos que puede contener un doble (o cualquier otro tipo de 64 bits).Double.MaxValue es igual a 1.79769313486232e308.

Ni siquiera;las codificaciones IEEE utilizan múltiples codificaciones para los mismos valores.Específicamente, NaN está representado por un exponente de todos los bits-1, y luego cualquier valor distinto de cero para la mantisa.Como tal, hay 252 NaN para dobles, 223 NaN para solteros.

Verdadero.No tuve en cuenta codificaciones duplicadas.Sin embargo, en realidad hay 252-1 NaN para dobles y 223-1 NaN para individuales.:pag

Doh, se me olvidó restar los infinitos.

La versión aproximada de este problema que aprendí es que los flotantes de 32 bits te dan 5 dígitos de precisión y los flotantes de 64 bits te dan 15 dígitos de precisión.Por supuesto, esto variará dependiendo de cómo estén codificados los flotantes, pero es un buen punto de partida.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top