Stejně jako v ostatních jazycích, tak i v PHP jsou čísla reprezentována ve dvojkové soustavě (soustava jedniček a nul), při některých matematických operacích proto může vycházet lehce odlišný výsledek, než bychom čekali. Tato stránka obsahuje přehled chování výpočtů v různých kontextech. Pro pochopení je potřeba aspoň základní znalost číslicové techniky a číselných soustav.
Způsob reprezentace čísel charakterizuje datový typ, například integer je převeden přímo ze zdrojového kódu z desítkové soustavy na dvojkovou (binární). O převod čísel se nemusíme vůbec starat, vše probíhá automaticky.
Důsledek tohoto převodu je, že maximální hodnota integeru (celé číslo) je určena podle počtu dostupných bitů v paměti. Na 32-bitovém PHP je rozsah od -2,147,483,648 do 2,147,483,647 (~ ± 2 miliardy), 64-bitové PHP má rozsah od -9,223,372,036,854,775,808 do 9,223,372,036,854,775,807 (~ ± 9 quintillionů). Maximální hodnotu můžeme vždy získat zavoláním konstanty PHP_INT_MAX.
Desetinná čísla se ukládají do datového typu float, který má omezenou přesnost, proto se interně ukládá jako dvojice čísel, které podléhají matematické operaci mantisa * (2 ^ exponent). Praktický důsledek je ten, že jsme schopni na malé množství bitů uložit i relativně velké číslo (v řádu miliard), akorát ne příliš přesně.
Důsledek použití datového typu float je, že výsledkem výpočtu 1 - 0.9 není přesně 0.1.
Příklad z webového fóra:
$x = 0.3;$y = 0.4;echo 0.7 - $x - $y; // vypíše -5.5511151231258E-17
Pokud ovšem čísla lehce upravíme:
$x = 6.5;$y = 7.5;echo 14.0 - $x - $y; // vypíše 0
Obecně o této problematice pojednává samostatný článek na webu VTM.e15.cz: Proč počítačům dělají problémy desetinná čísla, případně obecně o plovoucí řádové čárce na Wikipedii.
Obecně je dobré po výpočtu výsledek zaokrouhlit, nebo se desetinným číslům úplně vyhnout. Například cenu nebudeme ukládat v korunách (jako 14.90), ale v haléřích (jako 1490) a poté s ní pracovat přesně. O zaokrouhlování pojednává další kapitola článku.
$a = 5;$b = 3;echo $a + $b;
Pro operace lze použít běžné matematické zvyklosti, při kterých se respektuje přednost operátorů podle pravidel matematiky (násobení má přednost před sčítáním a podobně). Hodnoty lze zapsat přímo, nebo je načítat přes proměnné.
Možná to není na první pohled zřejmé, ale u matematického příkladu se nezapisuje znak rovnítka (
=). Z toho tedy vyplývá, že lze řešit jen jednoduchébinární operace, které vždy pracují jen sdvěma prvky(s rovnicemi nepočítejte, na to se musí použít specializovaná knihovna).
Ve sloupci
výsledekuvádím, co se vypíše za předpokladu, že:
$a = 5;$b = 3;$c = 10;
| Operace | Značka | Značka slovně | Příklad zápisu | Výsledek |
|---|---|---|---|---|
| Sčítání | + |
Plus | echo $a + $b; |
8 |
| Odčítání | - |
Mínus | echo $a - $b; |
2 |
| Násobení | * |
Hvězdička | echo $a * $b; |
15 |
| dělení | / |
Lomítko | echo $a / $b; |
1.66666666667 |
| Závorky | ( ) |
Závorky | echo $a + ($b * $c); |
35 |
| Spojování řetězců | . |
Tečka | echo $a . $b . $c; |
5310 |
| Zbytek po dělení | % |
Procento | echo $a % $b; |
2 |
| Přičtení jedničky | ++ |
dva plusy | echo $a++; |
6 |
| Odečtení jedničky | -- |
dva mínusy | echo $a--; |
4 |
| Mocnina | ** |
dvě hvězdičky | echo $a ** $b; |
125 |
Operátor mocniny (dvojitá hvězdička) je dostupný až od PHP 7.1. V jiných verzí PHP je nutné použít univerzální funkci
pow($a, $b).
Pokud řešíte nějaký běžný výpočetní úkol, tak s největší pravděpodobností již existuje funkce přímo v PHP, zde je jejich komentovaný přehled.
Běžné zaokrouhlení se provádí funkcí round(), má 3 parametry:
round(5); // 5round(5.1); // 5round(5.4); // 5round(5.5); // 6round(5.8); // 6round(5483.47621, 2); // 5483.47round(5483.47621, -2); // 5500
Dále existuje funkce floor() pro zaokrouhlení směrem dolů a funkce ceil() pro směr nahoru.
Pozor na datové typy!
Všechny zaokrouhlovací funkce vrací výsledek jako
floata to i v případě, že je výsledkem celé číslo.Pokud chceme s výsledkem pracovat jako s celým číslem, je důležité ho ještě dodatečně přetypovat. Například:
echo (int) round(3.14);
PHP pracuje s různými datovými typy, například u floatu se může snadno stát, že výsledkem funkce round() nebude číslo s konečným desetiným rozvojem. Pro výpis doporučuji použít funkci number_format(), o které pojednávám níže.
Používají se na hodně různých výpočtů a vychází z jednotkové kružnice. Využití je například při vykreslování kružnic, elips, posunů a podobně.
Výpočet úhlu z x a y. Převody kartézských a polárních souřadnic.
Vychází z jednotkové hyperboly. Jejich definice lze jednoduše popsat pomocí přirovnání:
Používají se například při generování terénu a fyzikální simulace.
Vychází z jednotkové hyperboly.
echo sin(30); // -0.98803162409286echo sin(deg2rad(30)); // 0.5echo cos(deg2rad(123)); // -0.54463903501503echo 1/tan(deg2rad(45)); // 1 (onen cotangens)echo sin(deg2rad(500)); // 0.64278760968654echo atan2(deg2rad(50), deg2rad(23)); // 1.1396575860761
Někdy se může stát, že budeme potřebovat zpracovat matematický výraz jako uživatelský řetězec, tedy třeba 5+2^(1+3/2).
V PHP neexistuje jednoduchý způsob, jak takový vstup zpracovat, ale naprogramoval jsem sérii knihoven, které tuto problematiku řeší.
Podrobnosti si přečtěte v samostatném článku Kalkulačka v PHP: Zpracování matematického výrazu jako řetězec.
Velká čísla a desetinná čísla se v PHP ukládají jako float, navíc se zaokrouhlují přibližně na 15 desetinných míst, což může být někdy nepříjemné. Proto vznikla knihovna BCMath Arbitrary Precision Mathematics.
Čísla se v této knihovně reprezentují jako string, proto nejsou limitovány nepřesností floatu, nicméně prováděné operace jsou o několik řádů pomalejší (ale stále jde o rychlejší způsob, než kdybychom si takovou funkci naprogramovali sami).
Pokud chceme získat například odmocninu ze 2 na 3 desetinná místa, tak stačí jen zavolat:
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:
Články a novinky nejen ze světa PHP a programování. Nenechte si ujít jediný článek.
Články píše Jan Barášek © 2009-2025 | Kontakt | Mapa webu
Status | Aktualizováno: ... | cs