2010-11-21 14 views
5

echo (int) ((0.1+0.7) * 10);Problemas de redondeo de números enteros de PHP

¿Por qué la salida anterior 7? Entiendo cómo PHP redondea hacia 0, pero no es (0.1+0.7) * 10 evaluado como un flotante y luego convertido como un entero?

Gracias!

+0

Creo que esto sucede en cualquier idioma, y ​​es porque la forma en que se manejan los números flotantes internamente – Quamis

Respuesta

7

Se produce una pérdida de precisión cuando los decimales se convierten internamente a su equivalente binario. El valor calculado será algo así como 7.9+ en lugar del esperado 8.

Si necesita un alto grado de precisión, use la familia de funciones GMP o la biblioteca bcmath.

+0

+1 Una biblioteca como 'bcmath' es el camino a seguir. –

0

no tengo php instalado, pero en Python:

$ python 
>>> 0.1+0.7 
0.79999999999999993 
>>> 

No todos los números en base 10 se pueden representar con precisión en el sistema de base 2. Compruebe artículo de Wikipedia:

sección Fracciones en binario. En particular, esta línea:

Fraction Decimal  Binary Fractional Approx. 
1/10 0.1  0.000110011... 1/16+1/32+1/256... 

1/10 no puede ser representado de una manera finita en base 2. Por lo tanto, 0.1 + 0.7 no se puede calcular precisamente en base 2.

Nunca asumen flotante los cálculos puntuales son precisos, tarde o temprano te morderán.

2

Véase el manual:

http://php.net/manual/en/language.types.float.php

Es típico que simples decimales fracciones como 0.1 o 0.7 no se pueden convertir en sus internos binarios homólogos sin una pequeña pérdida de precisión. Esto puede llevar a resultados confusos : por ejemplo, piso ((0.1 + 0.7) * 10) generalmente devuelve 7 en lugar de 8, , ya que la representación interna será será algo así como 7.9.

0

1/10 no se puede representar en un número finito de dígitos binarios, al igual que 1/3 no se puede representar como un número finito de dígitos de base 10. Por lo tanto, en realidad está sumando 0.09999999999999 ... y 0.69999999999999 ... la suma es casi 8, pero no del todo.

1

Las demás respuestas explicaron POR QUÉ esto sucede. Esto debe conseguir lo que quiere:

echo (int) round((0.1+0.7) * 10); 

Sólo ronda el flotador antes de echar a un int.

+0

también, se recomienda que no uses flotadores para los cálculos de monedas, debido a esta pérdida de precisión – Quamis

Cuestiones relacionadas