IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 14 - Matematické funkce ve Swift

V minulé lekci, Cykly ve Swift podruhé - repeat...while, break a continue, jsme ucelili naše znalosti cyklů dalšími konstrukcemi a klíčovými slovy, na která můžeme narazit v cizích zdrojových kódech.

Naše výuka Swift teď vlastně teprve začíná, nicméně tento on-line kurz těch nejzákladnějších konstrukcích jazyka již dokončujeme. Jsem rád, že jsme se úspěšně dostali až sem, další on-line kurz se totiž bude věnovat objektově orientovanému programování. Budeme tam vytvářet opravdu zajímavé aplikace a i jednu hru. Kurz zakončeme odlehčujícím článkem s přehledem matematických funkcí, které se nám v našich programech jistě budou v budoucnu hodit.

Základní matematické funkce jsou ve Swiftu obsaženy v modulu Foundation, který jinak potřebujete pro řadu další funkcionality. Již jsme se setkali se sqrt() pro získání odmocniny.

Máme k dispozici také matematické konstanty: M_PI a M_E. M_PI je pochopitelně číslo Pí (3.1415...) a E je Eulerovo číslo, tedy základ přirozeného logaritmu (2.7182...). Konstantu Pí můžeme získat i z typů Double nebo Float.

print("Pí: \(Double.pi) \ne: \(M_E)")

Výstup:

Pí: 3.14159265358979
e: 2.71828182845905

Pojďme si nyní popsat dostupné matematické funkce.

Dostupné matematické funkce

min(), max()

Začněme s tím jednodušším :) Obě funkce berou jako parametr dvě čísla libovolného datového typu. Funkce min() vrátí to menší, funkce max() to větší z nich.

round(), ceil(), floor() a trunc()

Všechny tyto funkce se týkají zaokrouhlování. round() bere jako parametr desetinné číslo a vrací zaokrouhlené číslo typu Double tak, jak to známe ze školy (od 0.5 nahoru, jinak dolů). ceil() (ceiling) zaokrouhlí vždy nahoru a floor() vždy dolů. trunc() (truncate) nezaokrouhluje, pouze odtrhne desetinnou část. Všechny tyto funkce očekávají typ Double, pro Float existují varianty s f na konci názvu, např.: roundf().

round() budeme jistě potřebovat často, další funkce jsem prakticky často použil např. při zjišťování počtu stránek při výpisu komentářů v knize návštěv. Když máme 33 příspěvků a na stránce jich je vypsáno 10, budou tedy zabírat 3.3 stránek. Výsledek musíme zaokrouhlit nahoru, protože v reálu stránky budou samozřejmě 4.

Pokud vás napadlo, že floor() a trunc() dělají to samé, chovají se jinak u záporných čísel. Tehdy floor() zaokrouhlí na číslo více do mínusu, trunc() zaokrouhlí vždy k nule.

Zaokrouhlení desetinného čísla a jeho uložení do proměnné typu Int tedy provedeme následujícím způsobem:

let d = 2.72
let a : Int = Int(round(d))

Přetypování na Int je nutné, jelikož round() vrací sice celé číslo, ale stále uložené v typu Double a to kvůli tomu, aby všechny matematické funkce pracovaly s typem Double.

abs(), sign a signum()

Častěji budete používat abs(), která vrátí absolutní (přeloženo: vždy kladnou) hodnotu čísla. Metoda signum() se volá na Int proměnných a vrátí podle znaménka -1, 0 nebo 1 (pro záporné číslo, nulu a kladné číslo).

Vlastnost sign pro typy Float a Double vrací FloatingPointSign, což je enum s hodnotami plus a minus. Plus dostanete pro 0 a kladná čísla, mínus pro záporná. Každopádně Apple v dokumentaci varuje, abychom nepoužívali tuto vlastnost k zjištění, jestli je hodnota záporná, protože může být NaN (Not-a-number).

sin(), cos(), tan()

Klasické goniometrické funkce, jako parametr berou úhel typu Double, který považují v radiánech, nikoli ve stupních. Pro konverzi stupňů na radiány stupně vynásobíme * (M_PI/180). Výstupem je opět Double. Funkce mají opět i Float varianty.

acos(), asin(), atan()

Klasické cyklometrické funkce (arkus funkce), které podle hodnoty goniometrické funkce vrátí daný úhel. Parametrem je hodnota v Double (a zase máme Float varianty), výstupem úhel v radiánech (také Double). Pokud si přejeme mít úhel ve stupních, vydělíme radiány / (180 / M_PI).

pow() a sqrt()

pow() bere dva parametry typu Double, první je základ mocniny a druhý exponent. Opět máme i další varianty. Pokud bychom tedy chtěli spočíst např. 23, kód by byl následující:

print(pow(2.0, 3.0))

sqrt() je zkratka ze SQuare RooT a vrátí tedy druhou odmocninu z daného čísla typu Double. Obě funkce vrací výsledek jako Double. Pro typ Float máme funkci sqrtf().

exp(), log(), log10()

exp() vrací Eulerovo číslo, umocněné na daný exponent. log() vrací přirozený logaritmus daného čísla. log10() vrací potom dekadický logaritmus daného čísla.

V seznamu metod nápadně chybí libovolná odmocnina. My ji však dokážeme spočítat i na základě poskytovaných matematických funkcí.

Víme, že platí: 3. odm. z 8 = 8^(1/3). Můžeme tedy napsat:

print(pow(8, (1.0/3.0)))

Je velmi důležité, abychom při dělení napsali alespoň jedno číslo s desetinnou tečkou, jinak bude Swift předpokládat celočíselné dělení a výsledkem by v tomto případě bylo 80 = 1.

Dělení

Programovací jazyky se často odlišují tím, jak v nich funguje dělení čísel. Tuto problematiku je nutné dobře znát, abyste nebyli poté (nepříjemně) překvapeni. Napišme si jednoduchý program:

let a : Int = 5 / 2
let b : Double = 5 / 2
let c : Double = 5.0 / 2
let d : Double = 5 / 2.0
let e : Double = 5.0 / 2.0
// let f : Int = 5 / 2.0

print("\(a)\n\(b)\n\(c)\n\(d)\n\(e)")

V kódu několikrát dělíme 5 / 2, což je matematicky 2.5. Jistě ale tušíte, že výsledek nebude ve všech případech stejný. Troufnete si tipnout si co kdy vyjde? Zkuste to :)

Kód by se nepřeložil kvůli řádku s proměnnou f, proto jsme ho zakomentovali. Problém je v tom, že v tomto případě vyjde desetinné číslo, které se snažíme uložit do čísla celého (Int). Výstup programu je poté následující:

2
2.5
2.5
2.5
2.5

Vidíme, že výsledek dělení je v prvním případě celočíselný a jinak reálný. Záleží na tom, do jakého typu ukládáme. Ačkoliv je v druhém případě dělení stejné jako v tom prvním, protože ukládáme do Double, tak máme desetinný výsledek. Pokud dělíme dvě celá čísla a výsledek ukládáme do Int, tak dostaneme opět celé číslo. Poslední možnost (s proměnnou f) nebude fungovat, protože dělíme 2.0 a Swift se snaží do celočíselné proměnné uložit Double.

Např. v jazyce PHP je výsledek dělení vždy desetinný. Až budete dělit v jiném programovacím jazyce než je Swift, zjistěte si jak dělení funguje než jej použijete.

Zbytek po celočíselném dělení

V našich aplikacích můžeme často potřebovat zbytek po celočíselném dělení (tzv. modulo). U našeho příkladu 5 / 2 je celočíselný výsledek 2 a modulo 1 (zbytek). Modulo se často používá pro zjištění zda je číslo sudé (zbytek po dělení 2 je 0), když chcete např. vybarvit šachovnici, zjistit odchylku vaší pozice od nějaké čtvercové sítě a podobně.

Ve Swift a obecně také v céčkových jazycích zapíšeme modulo jako %:

print(5 % 2) // Vypíše 1

Tak to bychom měli. Kurz bude pokračovat v sekci Základy objektově orientovaného programování ve Swift. Příště si tedy představíme objektový svět a pochopíme mnoho věcí, které nám až doteď byly utajovány :) Určitě si zkuste i cvičení.

V následujícím cvičení, Řešené úlohy k 11.-14. lekci Swift, si procvičíme nabyté zkušenosti z předchozích lekcí.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 18x (32.08 kB)
Aplikace je včetně zdrojových kódů v jazyce Swift

 

Předchozí článek
Cykly ve Swift podruhé - repeat...while, break a continue
Všechny články v sekci
Základní konstrukce jazyka Swift
Přeskočit článek
(nedoporučujeme)
Řešené úlohy k 11.-14. lekci Swift
Článek pro vás napsal Filip Němeček
Avatar
Uživatelské hodnocení:
7 hlasů
Autor se věnuje vývoji iOS aplikací (občas macOS)
Aktivity