Si todavía alguien llega a esta página con problemas similares donde la resta de números flotante causa valores extraños o erróneos. Quiero explicar este problema con un poco más de detalles. El culpable es el número de coma flotante. Y diferentes sistemas operativos y diferentes versiones de lenguajes de programación pueden comportarse de manera diferente.
Para ilustrar el problema, explicaré por qué con un simple ejemplo a continuación.
No está directamente relacionado con PHP y no es un error. Sin embargo, cada programador debe tener en cuenta este problema.
Este problema incluso costó muchas vidas hace dos décadas. El 25 de febrero de 1991, este problema en el cálculo de números flotantes en una batería de misiles Patriot MIM-104 impidió que interceptara un misil Scud entrante en Dhahran, Arabia Saudita, contribuyendo a la muerte de 28 soldados del Destacamento de Cuarteles del 14to. Ejército de los EE. UU.
¿Pero por qué sucede?
La razón es que los valores de coma flotante representan una precisión limitada. Por lo tanto, un valor podría no tener la misma representación de cadena después de cualquier procesamiento. También incluye escribir un valor de punto flotante en su secuencia de comandos y directamente imprimirlo sin ninguna operación matemática.
Sólo un ejemplo sencillo:
$a = '36';
$b = '-35.99';
echo ($a + $b);
era de esperar, para imprimir 0,01, ¿verdad? Pero imprimirá una respuesta muy extraña como 0.009999999999998
Al igual que otros números, los números de coma flotante dobles o flotantes se almacenan en la memoria como una cadena de 0 y 1.La forma en que el punto flotante difiere del número entero es en la forma en que interpretamos los 0 y los 1 cuando queremos verlos. Hay muchos estándares de cómo se almacenan.
números de coma flotante se empaquetan en general un dato equipo que el bit de signo, el campo exponente y la mantisa o mantisa, de izquierda a derecha ....
Los números decimales no están bien representados en binario debido a la falta de espacio suficiente. Entonces, no puedes expresar exactamente 1/3 ya que es 0.3333333 ... ¿verdad? Por qué no podemos representar 0.01 como un número flotante binario es por la misma razón. 1/100 es 0.00000010100011110101110000 ..... con una repetición de 10100011110101110000.
Si 0,01 se mantiene en forma simplificada y truncado sistema de 01000111101011100001010 en binario, cuando se traduce de nuevo a decimal, sería leído como 0,0099999. ... dependiendo del sistema (las computadoras de 64 bits le darán una precisión mucho mejor que las de 32 bits). El sistema operativo decide en este caso si imprimirlo como lo ve o cómo hacerlo de una manera más legible para el ser humano. Entonces, depende de la máquina cómo quieren representarlo. Pero puede protegerse en el nivel de idioma con diferentes métodos.
Si formatea el resultado, echo number_format (0.009999999999998, 2); imprimirá 0.01.
Esto se debe a que en este caso debe indicar cómo debe leerse y qué precisión necesita.
Investigue 'precision' en php.ini para ver cambios más amplios en todo PHP. Sin embargo, tenga en cuenta que está tratando con * dígitos significativos * allí. –