Operaciones aritméticas

Tipos de datos numéricos: enteros y decimales

Manual de PHP: Enteros - Decimales

PHP utiliza dos tipos de datos distintos para números: integer para números enteros y float para números decimales. Al escribir un número decimal, el separador entre la parte entera y la parte decimal es el punto (.), no la coma (,).

En PHP, los valores de enteros y decimales no pueden ser arbitrariamente grandes. Los valores máximos dependen de la arquitectura del procesador (32 o 64 bits), del sistema operativo y de la versión de PHP

Estos valores máximos (y otros relacionados) se guardan en varias constantes predefinidas (PHP_INT_MAX, PHP_FLOAT_MAX, etc), como se comenta en la lección Constantes y constantes predefinidas.

Si se necesita trabajar con enteros mayores que los valores máximos, es necesario utilizar las funciones bcmath.

Operaciones básicas

Los operadores aritméticos básicos son los siguientes:

Ejemplo Nombre Resultado
-$a Negación El opuesto de $a.
$a + $b Suma Suma de $a y $b.
$a - $b Resta Diferencia entre $a y $b.
$a * $b Multiplicación Producto de $a y $b.
$a / $b División Cociente de $a y $b.
$a ** $b Potenciación $a elevado a $b.

En general, el resultado de una operación es un número decimal si al menos uno de los números implicados es decimal. El resultado de una operación es entero solo cuando todos los números implicados son enteros, excepto si se trata de una división que da un resultado decimal o si el resultado es demasiado grande para representarlo mediante un entero.

Si el resultado de un cálculo con números enteros es demasiado grande para poderse representar con un entero, PHP lo convierte automáticamente en decimal, perdiéndose precisión.

<?php
print "<p>PHP_INT_MAX = " . PHP_INT_MAX . "</p>\n";
print "\n";
print "<p>PHP_INT_MAX - 1 = " . PHP_INT_MAX - 1 . "</p>\n";
print "\n";
print "<p>PHP_INT_MAX + 1 = " . PHP_INT_MAX + 1 . "</p>\n";
?>
Enlace a ejemplo

Si el resultado de un cálculo con números decimales es demasiado grande para poderse representar con un decimal, PHP lo convierte automáticamente en la constante INF.

<?php
print "<p>PHP_FLOAT_MAX = " . PHP_FLOAT_MAX . "</p>\n";
print "\n";
print "<p>PHP_FLOAT_MAX - 1 = " . PHP_FLOAT_MAX - 1E292 . "</p>\n";
print "\n";
print "<p>PHP_FLOAT_MAX + 1 = " . PHP_FLOAT_MAX + 1E292 . "</p>\n";
?>
Enlace a ejemplo

Cociente y resto de una división

El cociente y resto de una división están relacionados con el dividendo y divisor mediante la fórmula:

dividendo = divisor * cociente + resto

Cociente y resto de una división entre números enteros

Para calcular el cociente de una división entre números enteros, PHP dispone de la función intdiv($a, $b).

<?php
print "<p>El cociente de 17 dividido entre 3 es " . intdiv(17, 3) . "</p>\n";
?>
<p>El cociente de 17 dividido entre 3 es 5</p>

Para calcular el resto de una división entre números enteros, PHP dispone del operador "módulo" %.

<?php
print "<p>El resto de 17 dividido entre 3 es " . 17 % 3 . "</p>\n";
?>
<p>El resto de 17 dividido entre 3 es 2</p>

Se pueden emplear números negativos, pero hay que tener en cuenta que el resto tiene el mismo signo que el dividendo, como se observa en los siguientes ejemplos.

dividendo 17 divisor 3 2 resto 17 % 3 5 cociente intdiv(17, 3) 17 = 3 * 5 + 2 dividendo 17 divisor -3 2 resto 17 % -3 -5 cociente intdiv(17, -3) 17 = -3 * -5 + 2 dividendo -17 divisor 3 -2 resto -17 % 3 -5 cociente intdiv(-17, 3) -17 = 3 * -5 - 2 dividendo -17 divisor -3 -2 resto -17 % -3 5 cociente intdiv(-17, -3) -17 = -3 * 5 - 2

Nota: Como se comenta en la lección Varios, esta regla no se cumple en todos los lenguajes de programación.

¡Atención!Si se emplean números decimales con la función intdiv() o con el operador %, PHP genera un error E_DEPRECATED (concretamente, desde PHP 8.1), por lo que se aconseja no emplearlos. Además, hay que tener en cuenta que si se escriben números decimales, los números se truncan a enteros antes de efectuar el cálculo por lo que los resultados pueden no ser los esperados. Por ejemplo, intdiv(5, 1.5) da como resultado 5 y no 3 porque calcula el cociente de 5 entre 1, no el cociente de 5 entre 1.5. Y por ejemplo, 5 % 2.5 da como resultado 1 y no 0 porque calcula el resto de 5 entre 2, no el resto de 5 entre 2.5.

Cociente y resto de una división entre números decimales

Para calcular el cociente de una división entre números decimales, PHP no dispone de ninguna función u operador específico, aunque se puede recurrir al redondeo de la división entre los valores.

<?php
print "<p>El cociente de 17.1 dividido entre 3.1 es " . floor(17.1 / 3.1) . "</p>\n";
?>
  
<p>El cociente de 17.1 dividido entre 3.1 es 5</p>
<?php
print "<p>El cociente de -17.1 dividido entre 3.1 es " . ceil(-17.1 / 3.1) . "</p>\n";
?>
  
<p>El cociente de -17.1 dividido entre 3.1 es -5</p>

Para calcular el resto de una división entre números decimales, PHP dispone de la función fmod($a, $b).

<?php
print "<p>El resto de 17 dividido entre 3.1 es " . fmod(17, 3.1) . "</p>\n";
?>
  
<p>El resto de 17 dividido entre 3.1 es 1.5</p>

Se pueden emplear números negativos, pero hay que tener en cuenta que el resto tiene el mismo signo que el dividendo y que al redondear el cociente, si es positivo habrá que redondear hacia abajo (con floor()), pero si es negativo habrá que redondear hacia arriba (con ceil()), como se observa en los siguientes ejemplos.

dividendo 17.1 divisor 3.1 1.6 resto fmod(17.1, 3.1) 5 cociente floor(17.1 / 3.1) 17.1 = 3.1 * 5 + 1.6 dividendo 17.1 divisor -3.1 1.6 resto fmod(17.1, -3.1) -5 cociente ceil(17.1 / -3.1) 17.1 = -3.1 * -5 + 1.6 dividendo -17.1 divisor 3.1 -1.6 resto fmod(-17.1, 3.1) -5 cociente ceil(-17.1 / 3.1) -17.1 = 3.1 * -5 - 1.6 dividendo -17.1 divisor -3.1 -1.6 resto fmod(-17.1, -3.1) 5 cociente floor(-17.1 / -3.1) -17.1 = -3.1 * 5 - 1.6

Nota: Debido a la aproximación que supone trabajar con decimales, hacer la conversión con las operaciones de cociente y resto puede dar lugar a resultados incorrectos en algunos casos (normalmente, cuando el valor a convertir está muy próximo de valores que dan cero en la unidad más pequeña).

Potencias y raíces

El operador ** calcula potencias y raíces. PHP también dispone de la función pow(x, y) para calcular potencias y raíces.

<?php
print "<p>2<sup>3</sup> = " . 2 ** 3 . "</p>\n";
print "\n";
print "<p>2<sup>3</sup> = " . pow(2, 3) . "</p>\n";
?>

23 = 8

23 = 8

Tanto el operador como la función permiten calcular raíces, teniendo en cuenta que una raíz n-ésima es una potencia 1/n.

<?php
print "<p>La raíz cuadrada de 25 es " . 25 ** (1 / 2) . "</p>\n";
print "\n";
print "<p>La raíz cuadrada de 25 es " . 25 ** 0.5 . "</p>\n";
print "\n";
print "<p>La raíz cuadrada de 25 es " . pow(25, 1 / 2) . "</p>\n";
print "\n";
print "<p>La raíz cuadrada de 25 es " . pow(25, 0.5) . "</p>\n";
print "\n";
print "<p>La raíz cúbica de 1000 es " . 1000 ** (1 / 3) . "</p>\n";
print "\n";
print "<p>La raíz cúbica de 1000 es " . pow(1000, 1 / 3) . "</p>\n";
?>
<p>La raíz cuadrada de 25 es 5</p>

<p>La raíz cuadrada de 25 es 5</p>

<p>La raíz cuadrada de 25 es 5</p>

<p>La raíz cuadrada de 25 es 5</p>

<p>La raíz cúbica de 1000 es 10</p>

<p>La raíz cúbica de 1000 es 10</p>

En el caso de las raíces cuadradas, se puede utilizar también la función sqrt(x).

<?php
print "<p>La raíz cuadrada de 25 es " . sqrt(25) . "</p>\n";
?>
<p>La raíz cuadrada de 25 es 5</p>

Operadores de incremento y decremento

Ejemplo Nombre Efecto
++$a Pre-incremento Incrementa $a en uno, y luego devuelve $a.
$a++ Post-incremento Devuelve $a, y luego incrementa $a en uno.
--$a Pre-decremento Decrementa $a en uno, luego devuelve $a.
$a-- Post-decremento Devuelve $a, luego decrementa $a en uno.

La diferencia entre el pre-incremento y el post-incremento es que en el primer caso primero se incrementa la variable y después se utiliza y en el segundo primero se utiliza y después se incrementa.

<?php
$valor = 9;
print "<p>" . ++$valor . "</p>\n";
?>
<p>10</p>
<?php
$valor = 9;
print "<p>" . $valor++ . "</p>\n";
?>
<p>9</p>

El operador de incremento funciona también con caracteres, teniendo en cuenta que al incrementar el carácter 'z' se obtiene la cadena 'aa'. El operador de decremento no funciona con caracteres.

<?php
$valor = "b";
print "<p>" . ++$valor . "</p>\n";
?>
<p>c</p>
<?php
$valor = "z";
print "<p>" . ++$valor . "</p>\n";
?>
<p>aa</p>
<?php
$valor = "a9z";
print "<p>" . ++$valor . "</p>\n";
?>
<p>b0a</p>

Paréntesis

Los operadores aritméticos tienen el mismo orden de precedencia que en Matemáticas. Concretamente, el orden de precedencia de los operadores comentados anteriormente es, de mayor a menor, el siguiente (los operadores indicados en el mismo grupo se efectúan en el orden en que aparecen en la expresión):

Los paréntesis permiten agrupar operaciones de manera que las operaciones entre paréntesis se realicen antes que las operaciones fuera de los paréntesis. Se aconseja no utilizar paréntesis cuando las operaciones den el mismo resultado con o sin paréntesis.

Operadores combinados

Los operadores combinados permiten simplificar algunas expresiones de asignación:

Ejemplo Nombre Equivale a
$a += $b Suma $a = $a + $b
$a -= $b Resta $a = $a - $b
$a *= $b Multiplicación $a = $a * $b
$a /= $b División $a = $a / $b
$a %= $b Módulo $a = $a % $b

Redondear un número

La función round(x) redondea el número x al entero más próximo. En los valores intermedios (,5), redondea hacia arriba los valores positivos y hacia abajo los negativos.

<?php
print "<p>2.6 se redondea con round() a " . round(2.6) . "</p>\n";
print "<p>2.3 se redondea con round() a " . round(2.3) . "</p>\n";
print "<p>2.5 se redondea con round() a " . round(2.5) . "</p>\n";
print "<p>-2.6 se redondea con round() a " . round(-2.6) . "</p>\n";
print "<p>-2.3 se redondea con round() a " . round(-2.3) . "</p>\n";
print "<p>-2.5 se redondea con round() a " . round(-2.5) . "</p>\n";
?>
<p>2.6 se redondea con round() a 3</p>
<p>2.3 se redondea con round() a 2</p>
<p>2.5 se redondea con round() a 3</p>
<p>-2.6 se redondea con round() a -3</p>
<p>-2.3 se redondea con round() a -2</p>
<p>-2.5 se redondea con round() a -3</p>

La función round() se puede utilizar para verificar si un número es un número entero (positivo o negativo), comprobando si un número coincide con su valor redondeado.

<?php
$numero = 4.3;
if ($numero == round($numero)) {
    print "<p>$numero es un número entero</p>\n";
} else {
    print "<p>$numero no es un número entero</p>\n";
}

$numero = -6;
if ($numero == round($numero)) {
    print "<p>$numero es un número entero</p>\n";
} else {
    print "<p>$numero no es un número entero</p>\n";
}
?>
<p>4.3 no es un número entero</p>
<p>-6 es un número entero</p>

La función round(x,n) redondea x con n decimales (si n es negativo redondea a decenas, centenas, etc.).

<?php
print "<p>2.6574 se redondea con round() con dos decimales a " . round(2.6574, 2) . "</p>\n";
print "<p>3141592 redondeado con round() con centenas es " . round(3141592, -2) . "</p>\n";
?>
<p>2.6574 se redondea con round() con dos decimales a 2.66</p>
<p>3141592 redondeado con round() con centenas es 3141600</p>

La función floor(x) redondea el número x al entero inferior (es decir, devuelve la parte entera).

<?php
print "<p>2.6 se redondea con floor() a " . floor(2.6) . "</p>\n";
print "<p>2.3 se redondea con floor() a " . floor(2.3) . "</p>\n";
print "<p>-2.6 se redondea con floor() a " . floor(-2.6) . "</p>\n";
print "<p>-2.3 se redondea con floor() a " . floor(-2.3) . "</p>\n";
?>
<p>2.6 se redondea con floor() a 2</p>
<p>2.3 se redondea con floor() a 2</p>
<p>-2.6 se redondea con floor() a -3</p>
<p>-2.3 se redondea con floor() a -3</p>

La función ceil(x) redondea el número x al entero superior.

<?php
print "<p>2.6 se redondea con ceil() a " . ceil(2.6) . "</p>\n";
print "<p>2.3 se redondea con ceil() a " . ceil(2.3) . "</p>\n";
print "<p>-2.6 se redondea con ceil() a " . ceil(-2.6) . "</p>\n";
print "<p>-2.3 se redondea con ceil() a " . ceil(-2.3) . "</p>\n";
?>
<p>2.6 se redondea con ceil() a 3</p>
<p>2.3 se redondea con ceil() a 3</p>
<p>-2.6 se redondea con ceil() a -2</p>
<p>-2.3 se redondea con ceil() a -2</p>

Máximo y mínimo

Las funciones max() y min() devuelven el máximo y el mínimo, respectivamente, de una lista o matriz de valores..

<?php
print "<p>El máximo es " . max(20, 40, 25.1, 14.7) . "</p>\n";
?>
<p>El máximo es 40</p>
<?php
print "<p>El mínimo es " . min(20, 40, 25.1, 14.7) . "</p>\n";
?>
<p>El mínimo es 14.7</p>
<?php
$datos = [20, 40, 25.1, 14.7];
print "<p>El mínimo es " . min($datos) . "</p>\n";
?>
<p>El mínimo es 14.7</p>

Formatear un número

Para escribir un número con los símbolos de separación de decimales y de miles españoles, es decir, una coma (,) para separar la parte entera de la decimal y un punto (.) para separar las cifras de la parte entera en grupos de tres, se puede utilizar la función number_format().

<?php
print "<p>" . number_format(1300, 5) . "</p>\n";
?>
<p>1,300.00000</p>
<?php
print "<p>" . number_format(123456.789, 2) . "</p>\n";
?>
<p>123,456.79</p>
<?php
print "<p>" . number_format(123456789123, 0, ",", ".") . "</p>\n";
?>
<p>123.456.789.123</p>
<?php
print "<p>" . number_format(123456789123456.789, 2, ",", ".") . "</p>\n";
?>
<p>123.456.789.123.456,78</p>

La función requiere dos o cuatro argumentos:

La función devuelve el número formateado. Si sólo se utilizan dos argumentos, se utiliza el punto como separador de parte entera y decimal y la coma como separador de miles (notación inglesa).

Números aleatorios

Para obtener un número entero aleatorio entre dos valores determinados, se puede utilizar la función rand(), aunque esta función genera números aleatorios que no se pueden considerar criptográficamente seguros. En caso de necesitarse valores seguros, se puede utilizar la función random_int(), incorporada en PHP 7.0.

Normalmente, el primer argumento es el valor mínimo que se quiere obtener y el segundo argumento es el valor máximo que se quiere obtener, pero se pueden escribir al revés.

<?php
print "<p>" . rand(1, 6) . "</p>\n";
print "<p>" . rand(100, 150) . "</p>\n";
print "<p>" . rand(-20, -10) . "</p>\n";
?>
<p>5</p>
<p>135</p>
<p>-20</p>
<?php
print "<p>" . rand(6, 1) . "</p>\n";
print "<p>" . rand(150, 100) . "</p>\n";
print "<p>" . rand(-10, -20) . "</p>\n";
?>
<p>1</p>
<p>119</p>
<p>-18</p>

Si se llama a la función sin argumentos, esta devuelve un número entero aleatorio entre 0 y 2147483647. El valor 2147483647 (231 - 1) se debe a que PHP genera los números aleatorios mediante la versión de 32 bits del algoritmo Mersenne Twister y el valor 2147483647 es el mayor que puede almacenar PHP en una variable entera (véase PHP_INT_MAX).

<?php
print "<p>" . getrandmax() . "</p>\n";
print "<p>" . rand() . "</p>\n";
print "<p>" . rand() . "</p>\n";
?>
<p>2147483647</p>
<p>1334990778</p>
<p>19794827</p>

Como rand() sólo genera números enteros, si queremos generar números aleatorios con decimales podemos utilizar el "truco" de generar números más grandes multiplicando por la potencia de 10 necesaria y dividiendo después por la misma potencia.

Por ejemplo, para generar números con uno, dos o tres decimales entre 0 y 100:

<?php
print "<p>" . rand(0, 100 * 10) / 10 . "</p>\n";
?>
<p>43.1</p>
<?php
print "<p>" . rand(0, 100 * 100) / 100 . "</p>\n";
?>
<p>27.63</p>
<?php
print "<p>" . rand(0, 100 * 1000) / 1000 . "</p>\n";
?>
<p>8.944</p>