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
.
{SWIFT}
print("Pí: \(Double.pi) \ne: \(M_E)")
{/SWIFT}
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í:
{SWIFT}
print(pow(2.0, 3.0))
{/SWIFT}
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:
{SWIFT}
print(pow(8, (1.0/3.0)))
{/SWIFT}
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:
{SWIFT}
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)")
{/SWIFT}
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
%
:
{SWIFT}
print(5 % 2) // Vypíše 1
{/SWIFT}
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