Números de punto flotante

Los números de punto flotante (también conocidos como "de coma flotante" en español, y "floats" en inglés) pueden ser especificados usando cualquiera de las siguientes sintaxis:

<?php
$a 
1.234
$b 1.2e3
$c 7E-10;
?>

Formalmente:

LNUM          [0-9]+
DNUM          ([0-9]*[\.]{LNUM}) | ({LNUM}[\.][0-9]*)
EXPONENT_DNUM [+-]?(({LNUM} | {DNUM}) [eE][+-]? {LNUM})

El tamaño de un 'float' depende de la plataforma, aunque un valor común consiste en un máximo de aproximadamente 1.8e308 con una precisión cercana a los 14 dígitos decimales (el formato de 64 bit del IEEE).

Advertencia

Precisión del punto flotante

Los números de punto flotante tienen una precisión limitada. Aunque depende del sistema, PHP típicamente utiliza el formato de doble precisión IEEE 754, el cual dará un error relativo máximo por aproximación del orden de 1.11e-16. Las operaciones aritméticas elementales no podrán generar grandes errores y, por supuesto, se han de considrar los errores por propagación al componer varias operaciones.

Adicionalmente, los numeros racionales que son representables exactamente como números de punto flotante en base 10, como 0.1 o 0.7, no tienen una representación exacta como números de punto flotante en base 2, que es la base empleada internamente, sin importar el tamaño de la mantisa. Por lo tanto, no se pueden convertir en sus equivalentes binarios internos sin una pequeña pérdida de precisión. Esto puede conducir a resultados confusos: Por ejemplo, floor((0.1+0.7)*10) usualmente devolverá 7 en lugar del 8 previsto, ya que la representación interna será algo así como 7.9999999999999991118....

Por tanto, nunca se ha de confiar en resultados de números flotantes hasta el último dígito, y no comparar la igualdad de números de punto flotante directamente. Si fuera necesaria una mayor precisión, están disponibles las funciones matemáticas de precisión arbitraria y las funciones de gmp.

Para una explicación "simple", véase la » guía del punto flotante que también se titula "¿Por qué no sale la cuenta?"

Conversión al tipo float

Para más información sobre las conversiones de string a float, véase la Conversión de cadenas a números. Para valores de otros tipos, la conversión es la misma que si el valor hubiese sido convertido primero a integer y luego a float. Véase la Conversión a al tipo integer para más información. A partir de PHP 5, se genera un aviso si se intenta convertir un object a float.

Comparación del tipo float

Como se indica en la advertencia anterior, comprobar la igualdad de valores de punto flotante es problemático debido a la forma en que se representan internamente. Sin embargo, hay maneras de hacer comparaciones de los valores de punto flotante que evitan estas limitaciones.

Para comprobar la igualdad de valores de punto flotante, se utiliza un límite superior en el error relativo debido al redondeo. Este valor se conoce como el épsilon de la máquina o unidad de redondeo, y es la menor diferencia aceptable en los cálculos.

$a y $b son iguales en 5 dígitos de precisión.

<?php
$a 
1.23456789;
$b 1.23456780;
$épsilon 0.00001;

if(
abs($a-$b) < $épsilon) {
    echo 
"true";
}
?>

NaN

Algunas operaciones numéricas pueden resultar en un valor representado por la constante NAN. Este resultado representa un valor no definido o no representable mediante cálculos de punto flotante. Cualquier comparación, ya sea estricta o no, de este valor con cualquier otro valor, incluido él mismo, pero excepto TRUE, tendrá un resultado de FALSE.

Ya que NAN representa cualquier número de diferentes valores, NAN no debería compararse con otros valores, incluido él mismo; en su lugar debería comprobarse usando la función is_nan().