/
Matematica

Matematica in PHP

16. 02. 2020

Obsah článku

Come in altri linguaggi, i numeri in PHP sono rappresentati nel sistema binario (il sistema di uno e zero), quindi alcune operazioni matematiche possono produrre risultati leggermente diversi da quelli che ci aspetteremmo. Questa pagina dà una panoramica del comportamento dei calcoli in diversi contesti. Per la comprensione è richiesta almeno una conoscenza di base delle **tecniche numeriche** e dei **sistemi numerici**.

Rappresentazione dei numeri in memoria

Il modo in cui i numeri sono rappresentati è caratterizzato dal tipo di dati, per esempio integer è convertito direttamente dal codice sorgente da decimale a binario. Non dobbiamo preoccuparci di convertire i numeri, tutto viene fatto automaticamente.

La conseguenza di questa conversione è che il valore massimo di un intero è determinato dal numero di bit disponibili in memoria. Su 32-bit PHP la gamma è da -2.147.483.648 a -2.147.483.647 (~ ± 2 miliardi), 64-bit PHP ha una gamma da -9.223.372.036.854.775.808 a -9.223.372.036.854.775.807 (~ ± 9 quintilioni). Il valore massimo può sempre essere ottenuto chiamando la costante PHP_INT_MAX.

I numeri decimali sono memorizzati nel tipo di dati float, che ha una precisione limitata, quindi è memorizzato internamente come una coppia di numeri che sono soggetti all'operazione matematica mantissa * (2^esponente). La conseguenza pratica è che siamo in grado di memorizzare un numero relativamente grande (dell'ordine di miliardi) in un piccolo numero di bit, solo non molto preciso.

La conseguenza dell'uso del tipo di dati float è che il risultato del calcolo di 1 - 0.9 non è esattamente 0.1.

Esempio da web forum:

$x = 0.3;
$y = 0.4;
echo 0.7 - $x - $y; // stampa -5.5511151231258E-17

Se aggiustiamo leggermente i numeri:

$x = 6.5;
$y = 7.5;
echo 14.0 - $x - $y; // stampa 0

In generale, questo problema è discusso in un articolo separato su VTM.e15.cz: Perché i computer hanno problemi con i numeri decimali, o in generale su punto fisso su Wikipedia.

In generale, è una buona idea arrotondare il risultato dopo il calcolo, o evitare del tutto i decimali. Per esempio, memorizzate il prezzo non in corone (come 14,90) ma in centesimi (come 1490) e poi lavorate esattamente con esso. L'arrotondamento è discusso nella prossima sezione di questo articolo.

Operazioni matematiche

$a = 5;
$b = 3;
echo $a + $b;

Si possono usare convenzioni matematiche comuni per le operazioni, che rispettano la precedenza degli operatori secondo le regole della matematica (la moltiplicazione ha la precedenza sull'addizione, ecc.) I valori possono essere scritti direttamente o letti tramite le variabili.

Potrebbe non essere ovvio a prima vista, ma nell'esempio di matematica, il segno di uguale (=) non è scritto. Quindi, ne consegue che si possono risolvere solo semplici operazioni binarie, che funzionano sempre con solo due elementi (non contare le equazioni, devi usare una libreria specializzata per questo).

Panoramica degli operatori di base

Nella colonna risultato, elenco ciò che viene stampato assumendo:

$a = 5;
$b = 3;
$c = 10;

Operazione Segno Segno in parole Esempio di notazione Risultato
Aggiunta + Più echo $a + $b; 8
Sottrazione - Meno echo $a - $b; 2
Moltiplicazione * Asterisco echo $a * $b; 15
divisione / slash echo $a / $b; 1.66666666667
parentesi `( ) parentesi echo $a + ($b * $c); 35
concatenazione di stringhe . Periodo echo $a. $b. $c; 5310
Rimane dopo la divisione % Percentuale echo $a % $b; 2
Aggiungendo uno ++ due plus echo $a++; 6
Sottrarre uno -- due meno echo $a--; 4
Power ** due asterischi echo $a ** $b; 125

L'operatore di potenza (doppio asterisco) è disponibile solo a partire da PHP 7.1. Nelle altre versioni di PHP devi usare la funzione universale pow($a, $b).

Panoramica delle funzioni matematiche di base

Se state risolvendo qualche compito computazionale comune, molto probabilmente c'è già una funzione direttamente in PHP, ecco una panoramica commentata di esse.

Arrotondamento

L'arrotondamento normale è fatto con la funzione round(), ha 3 parametri:

  • Numero arrotondato
  • Opzionale: Precisione (fino a quante cifre decimali)
  • Opzionale: valore dimezzato (da quale valore arrotondare per eccesso)

round(5); // 5
round(5.1); // 5
round(5.4); // 5
round(5.5); // 6
round(5.8); // 6
round(5483.47621, 2); // 5483.47
round(5483.47621, -2); // 5500

C'è anche una funzione floor() per arrotondare per difetto e una ceil() per arrotondare per eccesso.

**Attenzione ai tipi di dati!

Tutte le funzioni di arrotondamento restituiscono il risultato come float, anche se il risultato è un intero.

Se volete trattare il risultato come un intero, è importante sovrascrivere il risultato. Per esempio: echo (int) round(3.14);

PHP lavora con diversi tipi di dati, per esempio con float può facilmente accadere che il risultato di round() non sia un numero con espansione decimale finita. Per l'output, raccomando di usare la funzione number_format(), di cui parlo sotto.

Funzioni goniometriche

Questi sono usati per molti calcoli diversi e sono basati sul cerchio unitario. Si usano, per esempio, per tracciare cerchi, ellissi, spostamenti e così via.

Funzioni ciclometriche

Calcola l'angolo da x e y. Conversione di coordinate cartesiane e polari.

Funzioni iperboliche

Basato sull'iperbole unitaria. Le loro definizioni possono essere facilmente descritte usando delle similitudini:

  • Ellisse, cerchio, cerchio con raggio 1
  • Iperbole, iperbole equiaxiale, iperbole unitaria

Sono utilizzati, per esempio, nella generazione del terreno e nella simulazione fisica.

Funzioni iperbolometriche

Basato sull'iperbole unitaria.

Esempi di utilizzo delle funzioni goniometriche

echo sin(30); // -0.98803162409286
echo sin(deg2rad(30)); // 0.5
echo cos(deg2rad(123)); // -0.54463903501503
echo 1/tan(deg2rad(45)); // 1 (onen cotangente)
echo sin(deg2rad(500)); // 0.64278760968654
echo atan2(deg2rad(50), deg2rad(23)); // 1.1396575860761

Calcolatrice - elaborazione di espressioni matematiche

A volte può succedere che abbiamo bisogno di elaborare un'espressione matematica come una stringa utente, per esempio 5+2^(1+3/2).

Non c'è un modo semplice per elaborare tali input in PHP, ma ho programmato una serie di librerie che affrontano questo problema.

Per i dettagli, vedi l'articolo separato Calculator in PHP: elaborare un'espressione matematica come una stringa.

Operazioni con grandi numeri e precisione dei calcoli

I numeri grandi e i decimali sono memorizzati come float in PHP, in più sono arrotondati a circa 15 cifre decimali, che a volte può essere fastidioso. Questo è il motivo per cui è stata creata la biblioteca matematica di precisione arbitraria.

I numeri sono rappresentati come stringhe in questa libreria, quindi non sono limitati dall'imprecisione di float, ma le operazioni eseguite sono diversi ordini di grandezza più lente (ma ancora più veloci che se programmassimo noi stessi una tale funzione).

Per esempio, se vogliamo ottenere una radice quadrata da 2 a 3 cifre decimali, basta chiamare:

echo bcsqrt('2', 3); // 1.414

Jan Barášek   Více o autorovi

Autor článku pracuje jako seniorní vývojář a software architekt v Praze. Navrhuje a spravuje velké webové aplikace, které znáte a používáte. Od roku 2009 nabral bohaté zkušenosti, které tímto webem předává dál.

Rád vám pomůžu:

Související články

1.
2.