PHP Manual
/
Matematika

Matematika v PHP

16. 02. 2020

Obsah článku

Podobne ako v iných jazykoch, aj v PHP sú čísla reprezentované v binárnej sústave (sústava jednotiek a núl), takže niektoré matematické operácie môžu priniesť trochu iné výsledky, ako by sme očakávali. Táto stránka poskytuje prehľad správania sa výpočtov v rôznych kontextoch. Na pochopenie sú potrebné aspoň základné znalosti **číselných techník** a **číselných sústav**.

Reprezentácia čísel v pamäti

Spôsob reprezentácie čísel je charakterizovaný dátovým typom, napríklad celé číslo sa priamo zo zdrojového kódu prevádza z desiatkovej sústavy na dvojkovú. O prevod čísel sa nemusíme vôbec starať, všetko sa vykonáva automaticky.

Dôsledkom tohto prevodu je, že maximálna hodnota celého čísla je určená počtom bitov, ktoré sú k dispozícii v pamäti. V 32-bitovom PHP je rozsah od -2 147 483 648 do -2 147 483 647 (~ ± 2 miliardy), v 64-bitovom PHP je rozsah od -9 223 372 036 854 775 808 do -9 223 372 036 854 775 807 (~ ± 9 kvintiliónov). Maximálnu hodnotu možno vždy získať volaním konštanty PHP_INT_MAX.

Desatinné čísla sú uložené v dátovom type float, ktorý má obmedzenú presnosť, takže je interne uložený ako dvojica čísel, na ktoré sa vzťahuje matematická operácia mantisa * (2^exponent). Praktickým dôsledkom je, že sme schopní uložiť relatívne veľké číslo (rádovo miliardy) do malého počtu bitov, len nie veľmi presne.

Dôsledkom použitia dátového typu float je, že výsledok výpočtu 1 - 0,9 nie je presne 0,1.

Príklad z webových fór:

$x = 0.3;
$y = 0.4;
echo 0.7 - $x - $y; // vytlačí -5,5511151231258E-17

Ak čísla mierne upravíme:

$x = 6.5;
$y = 7.5;
echo 14.0 - $x - $y; // vytlačí 0

Vo všeobecnosti sa o tejto problematike rozpráva v samostatnom článku na VTM.e15.cz: Prečo majú počítače problémy s desatinnými číslami, alebo všeobecne o plávajúcej bodke na Wikipédii.

Vo všeobecnosti je dobré výsledok po výpočte zaokrúhliť alebo sa desatinným číslam úplne vyhnúť. Napríklad cenu neukladajte v korunách (napríklad 14,90), ale v halieroch (napríklad 1490) a potom s ňou presne pracujte. Zaokrúhľovaniu sa venujeme v ďalšej časti tohto článku.

Matematické operácie

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

Pre operácie možno použiť bežné matematické konvencie, ktoré rešpektujú prioritu operátorov podľa pravidiel matematiky (násobenie má prednosť pred sčítaním atď.). Hodnoty možno zapisovať priamo alebo čítať prostredníctvom premenných.

Možno to nie je na prvý pohľad zrejmé, ale v matematickom príklade nie je napísané znamienko rovnosti (=). Z toho vyplýva, že sa dajú riešiť len jednoduché binárne operácie, ktoré vždy pracujú len s dvomi prvkami (nepočítajte rovnice, na to musíte použiť špecializovanú knižnicu).

Prehľad základných operátorov

V stĺpci výsledok uvádzam, čo sa vypíše za predpokladu:

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

Operácia Označenie Označenie slovami Príklad písania Výsledok
Sčítanie + Plus echo $a + $b; 8
Odčítanie - Mínus echo $a - $b; 2
Násobenie * Hviezdička echo $a * $b; 15
delenie / lomítko echo $a / $b; 1,6666666666667
zátvorky ( ) zátvorky echo $a + ($b * $c); 35
Zlučovanie reťazcov . Obdoba echo $a . $b . $c; 5310
Zvyšok po delení % Percentá echo $a % $b; 2
Pridanie jedného ++ dvoch plusov echo $a++; 6
Odpočítanie jednotky -- dva mínusy echo $a--; 4
Power ** dve hviezdičky echo $a ** $b; 125

Operátor power (dvojitá hviezdička) je k dispozícii až od verzie PHP 7.1. V ostatných verziách PHP musíte použiť univerzálnu funkciu pow($a, $b).

Prehľad základných matematických funkcií

Ak riešite nejakú bežnú výpočtovú úlohu, s najväčšou pravdepodobnosťou už existuje funkcia priamo v PHP, tu je ich komentovaný prehľad.

Zaokrúhľovanie

Bežné zaokrúhľovanie sa vykonáva pomocou funkcie round(), ktorá má 3 parametre:

  • Zaokrúhlené číslo
  • Voliteľné: Presnosť (na koľko desatinných miest)
  • Voliteľné: Polovičná hodnota (od akej hodnoty zaokrúhľovať nahor)

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

Existuje aj funkcia floor() na zaokrúhľovanie nadol a funkcia ceil() na zaokrúhľovanie nahor.

Pozor na dátové typy!

Všetky funkcie zaokrúhľovania vracajú výsledok ako float, aj keď je výsledkom celé číslo.

Ak chcete s výsledkom zaobchádzať ako s celým číslom, je dôležité prekryť typ výsledku. Napríklad: echo (int) round(3.14);

PHP pracuje s rôznymi dátovými typmi, napríklad pri type float sa môže ľahko stať, že výsledok funkcie round() nie je číslo s konečným desatinným rozšírením. Pre výpis odporúčam použiť funkciu number_format(), o ktorej hovorím nižšie.

Goniometrické funkcie

Používajú sa na množstvo rôznych výpočtov a vychádzajú z jednotkového kruhu. Používajú sa napríklad pri vykresľovaní kružníc, elips, posunov atď.

Cyklometrické funkcie

Vypočítajte uhol z hodnôt x a y. Prevody kartézskych a polárnych súradníc.

Hyperbolické funkcie

Na základe jednotkovej hyperboly. Ich definície sa dajú ľahko opísať pomocou prirovnaní:

  • Elipsa, kruh, kruh s polomerom 1
  • Hyperbola, Rovnovážna hyperbola, Jednotková hyperbola

Používajú sa napríklad pri generovaní terénu a fyzikálnej simulácii.

Hyperbolometrické funkcie

Na základe jednotkovej hyperboly.

Príklady použitia goniometrických funkcií

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

Kalkulačka - spracovanie matematických výrazov

Niekedy sa môže stať, že potrebujeme spracovať matematický výraz ako užívateľský reťazec, napríklad 5+2^(1+3/2).

Neexistuje jednoduchý spôsob, ako spracovať takýto vstup v jazyku PHP, ale naprogramoval som sériu knižníc, ktoré tento problém riešia.

Podrobnosti nájdete v samostatnom článku Kalkulátor v PHP: Spracovanie matematického výrazu ako reťazca.

Operácie s veľkými číslami a presnosť výpočtov

Veľké čísla a desatinné čísla sa v PHP ukladajú ako plávajúce, navyše sa zaokrúhľujú na približne 15 desatinných miest, čo môže byť niekedy nepríjemné. Preto bola vytvorená knižnica BCMath Arbitrary Precision Mathematics.

Čísla sú v tejto knižnici reprezentované ako reťazce, takže nie sú obmedzené nepresnosťou float, ale vykonávané operácie sú o niekoľko rádov pomalšie (ale stále rýchlejšie, ako keby sme takúto funkciu naprogramovali sami).

Ak napríklad chceme získať druhú odmocninu z 2 na 3 desatinné miesta, stačí zavolať:

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.
Status:
All systems normal.
2024