Úloha 3: Výpočet faktoriálu (n!)

Začátečník cyklus for intval() přetečení čísla MathML

Cíl úlohy

Vytvořte skript, který z formuláře načte celé číslo n a vypočítá jeho faktoriál n!. Skript musí správně zkontrolovat platnost zadaného čísla (celočíselnost, nezápornost) a ošetřit mezní situace (např. přetečení číselného rozsahu).

Definice faktoriálu (MathML)

Faktoriál přirozeného čísla n je součin všech kladných celých čísel menších nebo rovných n:

n! = ∏ i=1 n i = n⋅(n−1)⋅…⋅2⋅1

Podle definice dále platí konvence pro nulu: 0!=1.

Úvahy a doporučený postup řešení

  • Celočíselný cyklus: Použijte cyklus for ($i = 1; $i <= $n; $i++) a průběžně násobte proměnnou $faktorial. Výchozí hodnota násobitele musí být 1 (nikoliv 0!).
  • Ošetření necelých čísel: Pokud uživatel zadá např. 5.7, převedeme číslo na celočíselnou část pomocí intval($n).
  • Záporná čísla: Faktoriál v oboru reálných čísel není pro záporná celá čísla definován. Lze buď vypsat chybu, nebo záporné číslo převést na absolutní hodnotu (abs()) a uživatele o tom informovat.
  • Omezení velikosti čísla v PHP: Faktoriál roste extrémně rychle. Pro n>170 výsledek překročí maximální hodnotu 64bitového čísla s plovoucí řádovou čárkou (≈1,79⋅10308) a PHP vrátí hodnotu INF (nekonečno). Proto je vhodné výpočet omezit na n≤170.

Doplňující otázky k zamyšlení a náměty na rozšíření

  • 1. Proč 0!=1? Jaký kombinatorický význam má počet uspořádání nula prvků (prázdné množiny)?
  • 2. Co se stane v PHP s datovým typem proměnné, když faktoriál překročí maximální celé číslo PHP_INT_MAX? (PHP automaticky provede konverzi z int na float).
  • 3. Jak byste v PHP spočítali přesnou hodnotu 100! bez ztráty přesnosti na všech 158 číslic? (Nápověda: modul pro libovolnou přesnost BCMath nebo funkce gmp_fact).
  • 4. Zkuste vypsat kromě výsledku i celý rozepsaný součin, např. 5!=5⋅4⋅3⋅2⋅1=120.

Vyzkoušejte funkční řešení: Otevřít vzorovou úlohu faktorial.php