Black Friday Black Friday
Black Friday výprodej! Až 80 % extra bodů zdarma! Více informací zde

Lekce 11 - Matematické funkce v Kotlin

Kotlin Základy Matematické funkce v Kotlin American English version English version

Unicorn College ONEbit hosting Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V minulé lekci, Vícerozměrná pole v Kotlin, jsme si představili vícerozměrná pole. Naše výuka Kotlin 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 v Kotlin obsaženy v balíčku kotlin.math. Již jsme se setkali s funkcí sqrt() pro získání odmocniny.

Ve starších verzí jazyka se matematické funkce volaly na třídě Math, jako např. Math.sqrt(24.0). Dejte si pozor, abyste používali již nový zápis, kde se volají samostatně.

Import knihovny kotlin.math

Abychom mohli matematické funkce používat, musíme na začátek našeho souboru napsat:

import kotlin.math.*

Konstanty

Máme k dispozici matematické konstanty: PI a E. PI je pochopitelně číslo Pí (3.1415...) a E je Eulerovo číslo, tedy základ přirozeného logaritmu (2.7182...).

print("Pí: ${PI}\ne: ${E}")

Výstup:

Pí: 3.141592653589793
e: 2.718281828459045

Dostupné matematické funkce

Pojďme si nyní popsat funkce, které knihovna poskytuje.

Podpora datových typů na vstupu níže zmíněných funkcí je různá. Některé funkce jsou definované jen pro desetinná čísla a některé jen např. pro Double a Int, ale zas nepodporují Float. Již víme, že pokud napíšeme název funkce a stiskneme Ctrl + Space, ukáží se nám přetížení, tedy možné způsoby jak danou funkci můžeme zavolat.

Pokud byste chtěli např. použít funkci pow(), viz níže, pro čísla celá, je třeba tato čísla nejprve přetypovat např. na typ Double. Toho docílíme zápisem (3 as Double).pow(2), což by hodnotu 3 nejprve převedlo na desetinné číslo a poté umocnilo na druhou.

min(), max()

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

round(), ceil(), floor() a truncate()

Všechny tyto funkce se týkají zaokrouhlování. round() bere jako parametr desetinné číslo a vrací zaokrouhlené číslo typu Double nebo Float tak, jak to známe ze školy (od 0.5 nahoru, jinak dolů). ceil() (Ceiling) zaokrouhlí vždy nahoru a floor() vždy dolů. Všechny tyto funkce očekávají typ Double nebo Float.

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 truncate() dělají to samé, chovají se jinak u záporných čísel. Tehdy floor() zaokrouhlí na číslo více do mínusu, truncate() 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:

var d = 2.72
var a: Int = round(d).toInt()

abs() a sign()

abs() bere jako parametr libovolné číslo libovolného typu a vrátí jeho absolutní hodnotu. sign() bere na vstupu desetinné číslo a vrátí podle znaménka -1.0, 0.0 nebo 1.0 (pro záporné číslo, nulu a kladné číslo).

sin(), cos(), tan()

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

acos(), asin(), atan()

Opět klasické cyklometrické funkce (arkus funkce), které podle hodnoty goniometrické funkce vrátí daný úhel. Parametrem je hodnota jako desetinné číslo, výstupem úhel v radiánech (také desetinné číslo). Pokud si přejeme mít úhel ve stupních, vydělíme radiány / (180 / PI).

pow() a sqrt()

Metodu pow() nevoláme samostatně, ale na základu mocniny, který je typu Double nebo Int. Jako parametr bere exponent. Pokud bychom tedy chtěli spočíst např. 23, kód by byl následující:

println(2.0.pow(3))

Sqrt je zkratka ze square root a vrátí tedy druhou odmocninu z daného čísla typu Double nebo Float.

print(sqrt(24.0))

exp(), log(), log10(), log2()

exp() vrací Eulerovo číslo, umocněné na daný desetinný exponent. log() vrací přirozený logaritmus daného desetinného čísla. log10() vrací potom dekadický logaritmus daného desetinného čísla a log2() logaritmus se základem 2.

V seznamu funkcí nápadně chybí libovolná odmocnina. My ji však dokážeme spočítat i na základě funkcí, které knihovna kotlin.math poskytuje.

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

println(8.0.pow((1.0/3.0)))

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:

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

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

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 řádkům s proměnnou e a f, proto jsme je zakomentovali. Problém je v tom, že v těchto případech vyjde desetinné číslo, které se snažíme uložit do čísla celého (Int) nebo celé číslo do Double. Výstup programu je poté následující:

2
2.5
2.5
2.5

Vidíme, že výsledek dělení je někdy celočíselný a někdy reálný. Pokud je jedno z čísel desetinné, je výsledek vždy desetinné číslo. 2 celá čísla vrátí vždy zas celé číslo, dejte si na to pozor např. když budete počítat průměr, pro desetinný výsledek je nutné alespoň jednu proměnnou přetypovat na desetinné číslo.

Např. v jazyce PHP je výsledek dělení vždy desetinný. Až budete dělit v jiném programovacím jazyce než je Kotlin, 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ě.

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

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

Tak to bychom měli. Kurz pokračuje v sekci Základy objektově orientovaného programování v Kotlin. 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 cvičení, obsahuje nějaké věci s konzolí, co jsme si neukazovali a zajímavé projekty.


 

Stáhnout

Staženo 12x (6.92 kB)
Aplikace je včetně zdrojových kódů v jazyce Kotlin

 

 

Článek pro vás napsal Samuel Kodytek
Avatar
Jak se ti líbí článek?
Ještě nikdo nehodnotil, buď první!
Autor se věnuje všem jazykům okolo JVM. Rád pomáhá lidem, kteří se zajímají o programování. Věří, že všichni mají šanci se naučit programovat, jen je potřeba prorazit tu bariéru, který se říká lenost.
Miniatura
Předchozí článek
Vícerozměrná pole v Kotlin
Miniatura
Všechny články v sekci
Základní konstrukce jazyka Kotlin
Miniatura
Následující článek
Cvičení k 10.-11. lekci Kotlin
Aktivity (3)

 

 

Komentáře

Avatar
neutr
Člen
Avatar
neutr:4. května 5:50

Existuje také modulo pro double nebo float? Někdy je to vhodné například pro aproximace. Je mi jasné že se projevují problémy zejména s desetinným dělitelem. Samozřejmě to lze obejít celkem snadno například zvýšením a zaokrouhledním řádu, nebo rozdílem ale je zde ještě problém chyby a to už je jiné kafe.

 
Odpovědět 4. května 5:50
Avatar
gcx11
Redaktor
Avatar
Odpovídá na neutr
gcx11:16. června 0:10

Ano, existuje. Minimálně pro JVM verzi by se to mělo chovat stejně jako pro Javu:
https://docs.oracle.com/…/jls-15.html#…

 
Odpovědět  +1 16. června 0:10
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 2 zpráv z 2.