Índice de contenidos
Instalación en Windows
Instalación en Ubuntu
Servidores seguros
Páginas dinámicas
Sintaxis básica
Operaciones
Arrays
Formatos de presentación
Operadores
Bucles
Extraer y ord. información
Funciones
Ficheros externos
Imágenes dinámicas
Gestión de directorios
Cookies y sesiones
Clases y objetos
Ficheros en formato PDF
Bases de datos MySQL
PHP y XML
PDO - Bases SQLite / MySQL
MySQL a traves de misqli
Algo de JavaScript y AJAXOperaciones aritméticas
En páginas anteriores hemos podido ver que PHP permite utilizar un tipo de variables –las numéricas– cuyos valores puedan ser operados de la misma forma que se hace con los números en la vida cotidiana.
Los resultados de las operaciones pueden utilizarse de forma directa o ser recogidos en una nueva variable. Si asignamos a una nueva variable el resultado de una operación el valor contenido en ella no se modifica si cambian posteriormente los de las variables que intervinieron su creación.
Sintaxis de print y echo
Si queremos encadenar en una sola instrucción –echo ó print– el resultado de una operación junto con otras variables (o cadenas) es imprescindible poner entre paréntesis las instrucciones de la operación. Esta norma solo tiene dos excepciones: en caso de que el print solo contenga la propia operación o cuando utilicemos echo y el separador sea una coma.
Operadores aritméticos
Las diferentes operaciones aritméticas se realizan en PHP utilizando la siguiente sintaxis:
$a + $bDevuelve la suma de los valores númericos contenidos en las variables $a y $b.
$a – $bDevuelve la diferencia de los valores númericos contenidos en las variables $a y $b.
$a * $bDevuelve el producto de los valores númericos contenidos en las variables $a y $b.
$a / $bDevuelve el cociente de los valores númericos contenidos en las variables $a y $b.
(int)($a / $b)Devuelve el cociente entero de los valores númericos contenidos en las variables $a y $b.
$a % $bDevuelve el resto de la división entera de los valores númericos contenidos en las variables $a y $b.
Sqrt($a)Devuelve la raíz cuadrada del valor númerico contenido en la variables $a.
pow($a,$b)Devuelve el resultado de elevar el valor númericos contenido en la variable $a a la potencia indicada en la variable $b (ab)
pow($a,1/$b)Devuelve el resultado de elevar el valor númericos contenido en la variable $a a la potencia indicada en la variable 1/$b lo cual no es otra cosa que la raíz de índice $b de $a.
Abs($a);Devuelve el valor absoluto del valor númerico contenido en la variable $a.
<?php # definamos dos variables numéricas asignandoles valores $a=23; $b=34; /* hagamos una suma y escribamos directamente los resultados utilizando las instrucciones print y echo con todas sus posibles opciones de sintaxis */ print("La suma de $a + $b es: " . $a . "+" . $b . "=" . ($a+$b)."<br>"); print "La suma de $a + $b es: " . $a . "+" . $b . "=" . ($a+$b) ."<BR>"; print ("La suma de $a + $b es: " . $a . "+" . $b . "=" . ($a+$b) ."<BR>"); echo "La suma de $a + $b es: " . $a . "+" . $b . "=" . ($a+$b) ."<BR>"; echo "La suma de $a + $b es: " , $a , "+" , $b . "=" , ($a+$b) ."<BR>"; echo "La suma de $a + $b es: " , $a , "+" , $b , "=" , $a+$b ,"<BR>"; # guardemos ahora el resultado de esa operación en una nueva variable $c=$a+$b; /*ahora presentemos el resultado utilizando esa nueva variable adviertiendo el la salida */ print ("Resultados recogidos en una nueva variable<br>"); print "La suma de $a + $b es: " . $a . "+" . $b . "=" . $c ."<BR>"; print ("La suma de $a + $b es: " . $a . "+" . $b . "=" . $c ."<BR>"); echo "La suma de $a + $b es: " . $a . "+" . $b . "=" . $c ."<BR>"; echo "La suma de $a + $b es: " , $a , "+" , $b . "=" , $c ."<BR>"; echo "La suma de $a + $b es: " , $a , "+" , $b , "=" , $c ,"<BR>"; /* modifiquemos ahora los valores de $a y $b comprobando que el cambio no modifica lo contenido en la variable $c */ $a=513; $b=648; print ("<br> C sigue valiendo: " . $c ."<br>"); # experimentemos con los paréntesis en un supuesto de operaciones combinada # tratemos de sumar la variable $a con la variable $b # y multiplicar el resultado por $c. # Si escribimos print($a+$b*$c) nos hará la multiplicación antes que la suma print "<br>No he puesto paréntesis y el resultado es: ".($a+$b*$c); # Si escribimos print(($a+$b)*$c) nos hará la suma y luego multiplicará print "<br>He puesto paréntesis y el resultado es: ".(($a+$b)*$c); ?>
| Operaciones aritméticas | ||||
| Operación | Sintaxis | A | B | Resultado |
| Suma | $a+$b | 12 | -7.3 | 4.7 |
| Diferencia | $a-$b | 12 | -7.3 | 19.3 |
| Producto | $a*$b | 12 | -7.3 | -87.6 |
| Cociente | $a/$b | 12 | -7.3 | -1.64383561644 |
| Cociente entero | (int)($a/$b) | 12 | -7.3 | -1 |
| Resto de la división | $a%$b | 12 | 5 | 2 |
| Potencias ab | pow($a,$b) | 12 | 5 | 248832 |
| Potencias ab | pow($a,$b) | -7.3 | -3 | -0.00257058174836 |
| Raíz cuadrada | Sqrt($a) | 12 | 3.46410161514 | |
| Raíz cuadrada | Sqrt($a) | -7.3 | NAN | |
| Raíz enésima | pow($a,(1/$b) | 12 | 3 | 2.28942848511 |
| Valor absoluto | Abs($b) | -7.3 | 7.3 | |
Al realizar una operación cuyo resultado no es un número real PHP devuelve la cadena NaN tal como puedes ver en el ejemplo de la raíz cuadrada de un número negativo.
Redondeo de resultados
PHP dispone de tres opciones de redondeo:
floor($z)Redondeo por defecto
ceil($z)Redondeo por exceso
round($z)Redondeo tradicional
| Redondeos | ||||
| tipo | Sintaxis | A | Resultado | |
| Parte entera | (int)$a | 12 | 12 | |
| Parte entera | (int)$a | -7.3 | -7 | |
| Parte entera | (int)$a | -13.8546 | -13 | |
| Parte entera | (int)$a | -24.5 | -24 | |
| Parte entera | (int)$a | 13.8546 | 13 | |
| Parte entera | (int)$a | 24.5 | 24 | |
| Redondeo por defecto | floor($a) | 12 | 12 | |
| Redondeo por defecto | floor($a) | -7.3 | -8 | |
| Redondeo por defecto | floor($a) | -13.8546 | -14 | |
| Redondeo por defecto | floor($a) | -24.5 | -25 | |
| Redondeo por defecto | floor($a) | 13.8546 | 13 | |
| Redondeo por defecto | floor($a) | 24.5 | 24 | |
| Redondeo por exceso | ceil($a) | 12 | 12 | |
| Redondeo por exceso | ceil($a) | -7.3 | -7 | |
| Redondeo por exceso | ceil($a) | -13.8546 | -13 | |
| Redondeo por exceso | ceil($a) | -24.5 | -24 | |
| Redondeo por exceso | ceil($a) | 13.8546 | 14 | |
| Redondeo por exceso | ceil($a) | 24.5 | 25 | |
| Redondeo | round($a) | 12 | 12 | |
| Redondeo | round($a) | -7.3 | -7 | |
| Redondeo | round($a) | -13.8546 | -14 | |
| Redondeo | round($a) | -24.5 | -25 | |
| Redondeo | round($a) | 13.8546 | 14 | |
| Redondeo | round($a) | 24.5 | 25 | |
Orden de operación
Cuando una misma instrucción contiene una secuencia con varias operaciones el orden de ejecución de las mismas sigue los mismos criterios que las matemáticas. No se realiza una ejecución secuencial sino que se respeta el orden de prioridad matemático. Es decir, las potencias y raíces tienen prioridad frente a los productos y los cocientes, y estos, son prioritarios respecto a la suma y las diferencias.
Igual que en matemáticas se pueden utilizar los paréntesis para modificar el orden de ejecución de las operaciones, e igual que allí PHP también permite encerrar paréntesis dentro de paréntesis.
Punto flotante y precisión arbitraria
Las funciones aritméticas que estamos estudiando utilizan la sintaxis de punto flotante cuya precisión es limitada y, aunque depende del sistema, PHP típicamente utiliza el formato de doble precisión IEEE 754, el cual puede dar un error relativo máximo por aproximación del orden de 1.11*10–16.
Las operaciones aritméticas más elementales nunca van a dar grandes errores aunque la dimensión de estos podrá irse incrementando a medida que se concatenar varios de esos errores simples en operaciones compuestas.
Hay que tener en cuenta la existencia de fracciones que se pueden representar de forma exacta como números de punto flotante en base 10 (por ejemplo 1/10 ó 7/10) pero que carecen de esa exactitud al ser expresados en base 2 que es la usada internamente por PHP.
Así pues, hemos de tener cuidado al considerar números de coma flotante hasta su último dígito por los imprevisibles efectos –sobretodo a la hora de la comparación– de esos errores en el resultado.
Para operaciones matemáticas que necesiten una mejor precisión PHP (innecesaria en el ámbito cotidiano y limitada a casos muy puntuales del ámbito científico) ofrece la calculadora binaria que soporta números de cualquier tamaño y precisión representados como cadenas. Las funciones que utilizan esa forma de cálculo son las siguientes:
bcadd($a,$b,c)Devuelve la suma de los valores numéricos contenidos en las cadenas $a y $b con una precisión (número de cifras decimales) especificada por el número entero especificado en el parámetro c.
bcsub($a,$b,c)Devuelve la diferencia entre los valores numéricos contenidos en las cadenas $a y $b con una precisión (número de cifras decimales) especificada por el número entero especificado en el parámetro c.
bcmul($a,$b,c)Devuelve el producto de los valores numéricos contenidos en las cadenas $a y $b con una precisión (número de cifras decimales) especificada por el número entero especificado en el parámetro c.
bcdiv($a,$b,c)Devuelve el resultado de dividir los valores numéricos contenidos en las cadenas $a y $b con la precisión especificada por el número entero contenido en el parámetro c.
bcmod($a,$b)devuelve el resto de la división entera de los valores contenidos en las cadenas $a y $b.
bcpow($a,$b,c)Devuelve el resultado de elevar el valor numérico contenido en la cadena $a a la potencia expresada por la cadena $b dando el resultado con la cantidad de decimales señalada por el parámetro c.
Devuelve la raíz cuadrada del valor numérico contenido en la cadena $a con la cantidad de decimales señalada por el parámetro c.
bccomp($a,$b,c)Compara los valores contenidos en las cadenas $a y $b teniendo en cuenta únicamente el número de decimales especificados en c. Si $a>$b devuelve 1. Si las magnitudes comparadas son iguales devuelve 0 y si son distintas devuelve 1.
Si comparamos $a='3.456' (es necesario indicar siempre los valores como cadenas) con $b='3.45' obtendremos como resultado:
bccomp($a,$b,0)=0 Compara 3 con 3 que obviamente son igualesEn el cuadro puedes ver, señalados en rojo, los resultados de efectuar la misma operación utilizando el operador de coma flotante y estas funciones de precisión arbitraria. Si comparas las diferencias en los resultados obtenidos con cada una de ellas podrás darte idea del error provocado por los inevitables redondeos de la operación con coma flotante.
Comparación de punto flotante y precisión arbitraria
| Comparación de funciones matemáticas | ||||
| Operación | Variable | Valor | ||
| S U M A | $A | "12345678910123456789012345678901234567890" | ||
| $B | "45678910123456789012345678901234567890123" | |||
| bcadd($A,$B,0) | 58024589033580245801358024580135802458013 | |||
| $a=(double)$A | 1.23456789101E+40 | |||
| $b=(double)$B | 4.56789101235E+40 | |||
| $a+$b | 5.80245890336E+40 ó 58024589033580236333428572634998418440192 | |||
| $C | "0.0002345678902" | |||
| $D | "0.00000000000000000000000000000000000000001523786" | |||
| bcadd($C,$D,50) | 0.00023456789020000000000000000000000000001523786000 | |||
| $c=(double)$C | 0.0002345678902 | |||
| $d=(double)$D | 1.523786E-41 | |||
| $c+$d | 0.0002345678902 ó 0,00023456789020000001029161995624860992393223568797 | |||
| R E S T A | $A | "12345678910123456789012345678901234567890" | ||
| $B | "45678910123456789012345678901234567890123" | |||
| bcsub($A,$B,0) | -33333231213333332223333333222333333322233 | |||
| $a=(double)$A | 1.23456789101E+40 | |||
| $b=(double)$B | 4.56789101235E+40 | |||
| $a-$b | -3.33332312133E+40 ó -33333231213333327795815413198205132734464 | |||
| $C | "0.0002345678902" | |||
| $D | "0.00000000000000000000000000000000000000001523786" | |||
| bcsub($C,$D,50) | 0.00023456789019999999999999999999999999998476214000 | |||
| $c=(double)$C | 0.0002345678902 | |||
| $d=(double)$D | 1.523786E-41 | |||
| $c-$d | 0.0002345678902 ó 0,00023456789020000001029161995624860992393223568797 | |||
| P R O D U C T O | $A | "12345678910123456789012345678901234567890" | ||
| $B | "45678910123456789012345678901234567890123" | |||
| bcmul($A,$B,0) | 56393715734858534797546128354926080723008626986848 1383972550423718379870903950470 | |||
| $a=(double)$A | 1.23456789101E+40 | |||
| $b=(double)$B | 4.56789101235E+40 | |||
| $a*$b | 5.63937157349E+80 ó 56393715734858529559076134525051001632068799181691 5078270593363632973621514731520 | |||
| $C | "0.0002345678902" | |||
| $D | "0.00000000000000000000000000000000000000001523786" | |||
| bcmul($C,$D,62) | 0.000000000000000000000000000000000000000000003574 312671362972 | |||
| $c=(double)$C | 0.0002345678902 | |||
| $d=(double)$D | 1.523786E-41 | |||
| $c*$d | 3.57431267136E-45 ´0 0,000000000000000000000000000000000000000000003574 31267136297184 | |||
| D I V I S I Ó N | $A | "12345678910123456789012345678901234567890" | ||
| $B | "45678910123456789012345678901234567890123" | |||
| bcdiv($A,$B,30) | 0.270270872854818178953756836882 | |||
| $a=(double)$A | 1.23456789101E+40 | |||
| $b=(double)$B | 4.56789101235E+40 | |||
| $a/$b | 0.270270872855 ó 0,270270872854818211550309570157 | |||
| $C | "0.0002345678902" | |||
| $D | "0.00000000000000000000000000000000000000001523786" | |||
| bcdiv($C,$D,30) | 15393755435474535138136194977509965310.08947450626 2690430283517501801 | |||
| $c=(double)$C | 0.0002345678902 | |||
| $d=(double)$D | 1.523786E-41 | |||
| $c/$d | 1.53937554355E+37 ó 15393755435474538599292516471769399296,00000000000 0000000000000000000 | |||
| R E S T O S | $A | "12345678910123456789012345678901234567890" | ||
| $B | "57" | |||
| bcmod($A,$B) | 19 | |||
| $a=(double)$A | 1.23456789101E+40 | |||
| $b=(double)$B | 57 | |||
| $a % $b | 0 | |||
| P O T E N C I A | $A | "12345678910123456789012345678901234567890" | ||
| $B | "13" | |||
| bcpow($A,$B) | 15477282435120092620517640487873307882539433894477 02478876805675247359287360605519476488004915460644 30130253272627846453956411651820029120439549209342 64779279536097719586538292066102759581864670705845 47341619065960659102701030110334399943453939049941 81961179086427277645221130645386339095405377300948 55610257804029129290263282188925049521874093123594 94558994966581650612470024575134583192369561297975 69626211024080786875604177270092747586939296603680 65512433192215011092075340601280601173670507434702 7729224690000000000000 | |||
| $a=(double)$A | 1.23456789101E+40 | |||
| $b=(double)$B | 13 | |||
| pow($a, $b) | INF ó inf | |||
| $A | "12345678910123456789012345678901234567890" | ||
| $B | "13" | |||
| bcsqrt($A,15) | 111111110651111110153.9111071478030905799220364 | |||
| $a=(double)$A | 1.23456789101E+40 | |||
| $b=(double)$B | 13 | |||
| Sqrt($a) | 1.11111110651E+20 ó 111111110651111112704,0000000000000000000000000 | |||
Aunque las diferencias de resultados puedan parecer muy grandes en valor absoluto (hemos exagerado premeditadamente los valores operados (tanto en valores grandes como en valores pequeños) los errores relativos son de escasa significación. En la inmensa mayoría de las situaciones (por no decir todas las cotidianas) resulta suficiente utilizar los operadores de coma flotante.