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 12 - Matematické funkce v Dartu a knihovna dart:math

V minulé lekci, Vnořené seznamy v Dartu, jsme si představili vnořené seznamy. Tento Dart tutoriál věnujeme přehledu matematických metod, které se nám v našich programech jistě budou v budoucnu hodit.

Základní matematické metody jsou v Dartu v knihovně dart:math. Třída nám poskytuje základní konstanty: E, PI, dále i druhou odmocninu z čísla 2 (SQRT2) a z 1/2 (SQRT1_2) a několik předpočítaných logaritmů LN10, LN2, LOG2E a LOG10E. PI je pochopitelně číslo Pí (3.1415...) a E je Eulerovo číslo, tedy základ přirozeného logaritmu (2.7182...). Asi je jasné, jak se konstantami této knihovny pracuje, ale pro jistotu si na ukázku konstanty vypišme do konzole:

print('Pí: $PI');
print('e: $E');
print('2. odmocnina ze 2: $SQRT2');
print('2. odmocnina z 1/2: $SQRT1_2');
print('Logaritmus čísla 10 o základu e: $LN10');
print('Logaritmus čísla 2 o základu e: $LN2');
print('Logaritmus čísla e o základu 2: $LOG2E');
print('Logaritmus čísla e o základu 10: $LOG10E');

Výstup programu:

Konzolová aplikace
Pí: 3.141592653589793
e: 2.718281828459045
2. odmocnina ze 2: 1.4142135623730951
2. odmocnina z 1/2: 0.7071067811865476
Logaritmus čísla 10 o základu e: 2.302585092994046
Logaritmus čísla 2 o základu e: 0.6931471805599453
Logaritmus čísla e o základu 2: 1.4426950408889634
Logaritmus čísla e o základu 10: 0.4342944819032518

Pojďme si nyní popsat metody, které třída poskytuje:

Metody knihovny dart:math

min() a 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.

sin(), cos(), tan()

Klasické goniometrické funkce, jako parametr berou úhel v radiánech typu num (tj. int nebo double). Pro konverzi stupňů na radiány stupně vynásobíme * (PI / 180). Výstupem je double.

acos(), asin(), atan(), atan2()

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

Funkce atan2() je čtyřkvadrantová varianta funkce atan(), jako parametr bere 2 čísla a, b a pokud je b kladné, výsledek je stejný jako atan(b / a). Funkce atan2() je tedy vhodná pro převod z kartézských souřadnic do souřadnic polárních.

pow() a sqrt()

Funkce pow() bere dva parametry typu (num), první je základ mocniny a druhý exponent. Vrací výsledek jako int, nebo, pokud alespoň jeden parametr byl typu double, vrací výsledek jako double. Pokud bychom tedy chtěli spočíst např. 23, kód by byl následující:

print(pow(2, 3));

sqrt() je zkratka ze square root a vrátí tedy druhou odmocninu z daného čísla typu num. Výsledek vrací jako double.

exp(), log()

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

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

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

print(pow(8, 1/3));

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:

//int a = 5 / 2;
int a2 = (5 / 2).toInt();
int a3 = 5 ~/ 2;

double b = 5 / 2;
double c = 5.0 / 2;
double d = 5 / 2.0;
double e = 5.0 / 2.0;

print('$a2\n$a3\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 nespustil kvůli řádku s proměnnou a, proto jsme ho zakomentovali. Problém je v tom, že v tomto případě vyjde desetinné číslo (kvůli dělení), které se snažíme uložit do čísla celého (int). Výstup programu je poté následující:

Konzolová aplikace
2
2
2.5
2.5
2.5
2.5

Vidíme, že výsledek se shoduje s tím, co bychom očekávali v matematice. Celočíselný je tehdy, když výsledek po dělení převedeme na int metodou toInt(), nebo pokud použijeme celočíselné dělení ~/. Naopak, výsledek každého dělení je vždy desetinný.

V Dartu nelze přiřadit celočíselný literál (např. 4) do typu double a naopak i třebas "hezký" desetinný literál do typu int (např. 4.0).

// double x = 4;
double x = 4.toDouble();

// int y = 4.0;
int y = 4.0.toInt();

Pozn.: V jiných programovacích jazycích toto nemusí být pravidlem a chování se může lišit. Dávejte si na tuto problematiku pozor.

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í dvojkou je 0), když chcete např. vybarvit šachovnici, zjistit odchylku vaší pozice od nějaké čtvercové sítě a podobně.

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

print(5 % 2);

print('Výsledek 5 / 2 je ${5 ~/ 2} a zbytek je ${5 % 2}.');

Metody na typu num

Jak jsme si již zmiňovali dříve, přímo datový typ num (z kterého vychází int i double) má spoustu dalších metod. Řekneme si něco tedy i o nich.

round(), roundDouble(), floor(), floorToDouble(), ceil(), ceilToDouble()

Všechny funkce zaokrouhlují číslo. Funkce round() se chová jako klasické zaokrouhlování v matematice, floor() naopak zaokrouhluje pouze dolu, ceil() zas pouze nahoru(). Všechny 3 funkce vrací typ int a mají i varianty (s postfixem ...toDouble()), které vracejí typ double.

print('round: ${k.round()}, ${l.round()}, ${m.round()}');
print('floor: ${k.floor()}, ${l.floor()}, ${m.floor()}');
print('ceil: ${k.ceil()}, ${l.ceil()}, ${m.ceil()}');

Výstup programu:

Konzolová aplikace
round: 4, 4, 5
floor: 4, 4, 4
ceil: 4, 5, 5

toInt(), toDouble(), toString()

Všechna čísla lze převádět mezi celočíselnou a desetinnou reprezentací, případně převést i do řetězce.

abs() a sign()

Funkce abs() vrací absolutní hodnotu, sign() vrací podle znaménka -1, 0 nebo 1 (pro záporné, nulu a kladné číslo).

isFinite, isInfinite, isNegative

Čísla mají také vlastnosti, které nám pomohou určit, zda-li je číslo konečné, nekonečné nebo záporné.

Tak to bychom měli práci s matematickými funkcemi. V příštím lekci, Řešené úlohy k 11.-12. lekci Dartu, si něco povíme o hodnotě null a jak s ní pracovat. Blížíme se ke konci :-)

V následujícím cvičení, Řešené úlohy k 11.-12. lekci Dartu, 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 6x (1.8 kB)
Aplikace je včetně zdrojových kódů v jazyce Dart

 

Předchozí článek
Vnořené seznamy v Dartu
Všechny články v sekci
Základní konstrukce jazyka Dart
Přeskočit článek
(nedoporučujeme)
Řešené úlohy k 11.-12. lekci Dartu
Článek pro vás napsal Honza Bittner
Avatar
Uživatelské hodnocení:
1 hlasů
FIT ČVUT alumnus :-) Sleduj mě na https://twitter.com/tenhobi a ptej se na cokoli na https://github.com/tenhobi/ama.
Aktivity