# Matematické funkce a operace s čísly

## Základní matematické funkce a operace s nimi

- Základní matematické funkce
	- Funkce velmi často potřebné při běžných výpočtech
	- Poskytovány třídou ```java.lang.Math``` (tj. třída Math je umístěna v balíku java.lang a není ji tedy třeba importovat)
	- statické metody, musí se tedy **volat s názvem třídy**
		- např. ```Math.jménoMetody();```
	- Většina metod má parametry typu ```double``` a vrací typ ```double```
		- Pro většinu běžných matematických výpočtů se normálně používají reálná čísla
		- Někdy mají i celočíselnou variantu, takže podle toho, zda jsou parametry ```int``` nebo ```double```, vrátí ```int``` nebo ```double```
	- Kromě metod obsahuje konstanty
		- ```Math.PI``` – hodnota π
		- ```Math.E``` – hodnota e
	- příklad metod
		- Absolutní hodnota 
			- ```Math.abs(i);```
		- Větší a menší číslo
			- ```Math.max(i, j);```
			- ```Math.min(d, e);```
		- Zaokrouhlování
			- ```Math.round(e);```

### Generování (pseudo)náhodných čísel v Javě

- Třída ```Math```
	- Obsahuje metodu ```random()```, která vrací reálné náhodné číslo (typu ```double```) z intervalu <0.0; 1.0)
	- Např. ```double nahodne = Math.random();```
- Třída ```Random```
	- Třída věnovaná náhodným číslům
		- Je umístěná v balíku ```java.util```, před jejím použitím je tedy nutno použít import ```import java.util.Random;```
	- Obsahuje různé metody pro generování náhodných čísel s různými pravděpodobnostními rozděleními
	- Metody třídy ```Random``` nejsou statické, proto se nevolají nad názvem třídy (jako metody třídy ```Math```)
		- Je nutná inicializace podobně jako u třídy ```Scanne```
		- ```Random r = new Random();```
			- Inicializuje třídu ```Random``` pro generování náhodných čísel s výchozí hodnotou získanou ze systémového času
			- Při každém spuštění programu se vygeneruje jiná posloupnost náhodných čísel
		- ```Random r = new Random(výchozíHodnota)```
			- Inicializuje třídu ```Random``` pro generování náhodných čísel se zadanou výchozí hodnotou (celé číslo typu ```long```)
			- Při každém spuštění programu se vygeneruje stejná posloupnost náhodných čísel
			- Je jedno, jakou výchozí hodnotu zadáme (vhodné může být např. ```1```), podstatné je, že je konstantní (při každém spuštění stejná)
		- Metody se potom volají nad proměnnou ```r```
	- Dvě velmi často používané metody
		- ```int nextInt(int max)```
			- Vrací celé číslo z intervalu <0; max – 1>
		- ```double nextDouble()```
			- Vrací reálné číslo z intervalu <0; 1)
			- Funguje stejně jako metoda ```Math.random();```

## Problémy při provádění aritmetických operací

- Při provádění aritmetických operací může nastat několik problémů, se kterými je potřeba počítat

### Výsledky celočíselných aritmetických operací implicitně typu int

- Výsledky celočíselných aritmetických operací (tj. hodnota výrazu) jsou v jazyce Java implicitně typu ```int```
	- Výjimkou je datový typ ```long``` – pokud je alespoň jeden operand typu ```long```, výsledek aritmetické operace je typu ```long```
- Pokud používáme pouze typ ```int```, s problémem se nesetkáme
- Pokud používáme datové typy s menším rozsahem (```byte, short```), je potřeba výslednou hodnotu výrazu před přiřazením přetypovat

### Celočíselné vs. reálné dělení

- V jazyce Java existuje pouze jeden operátor pro dělení – lomítko „/“, který se používá pro celočíselné dělení (tj. dělení se zbytkem) i reálné dělení
	- Typ provedeného dělení záleží na obou operandech
	- Pokud jsou oba operandy celá čísla (např. typu ```int```), výsledek je celé číslo – podíl získaný celočíselným dělením
	- Pokud je alespoň jeden operand nebo oba operandy reálná čísla (např. typu double), výsledek je reálné číslo – podíl získaný reálným dělením (obecně desetinné číslo)

### Přetečení a podtečení

- Přetečení
	- Nastane, pokud do proměnné daného typu uložíme větší hodnotu, než je kapacita daného datového typu
	- Např. do proměnné typu ```byte``` uložíme hodnotu 130 (maximální kladná hodnota uložitelná do ```byte``` je 127
	- To nelze udělat přímo – dojde k chybě při překladu, ale snadno se to stane při ukládání výsledku aritmetické operace nebo při nevhodném přetypování
	- Výsledek přetečení je uložení jiné hodnoty (často s opačným znaménkem, ale není to pravidlo)
	- POZOR! – Přetečení není detekováno jako chyba, program se normálně přeloží a spustí => Zda k přetečení dojde, závisí na hodnotách operandů
- Podtečení
	- Může nastat pouze u reálných čísel (u čísla nebo jeho exponentu)
	- Hodnota, kterou se pokoušíme uložit, je menší než nejmenší zobrazitelná hodnota daným datovým typem (```float``` nebo ```double```)
	- Reálná čísla nemají nekonečnou přesnost, mají omezený počet desetinných míst, pokud uložíme velmi malé nenulové číslo (např. 1E-300), může se stát, že bude uloženo jako 0.0

### Porovnávání reálných čísel

- Reálná čísla nemají nekonečnou přesnost, mají omezený počet desetinných míst – dochází k zaokrouhlování
- Proto není vhodné zjišťování, zda jsou dvě reálná čísla shodná, provádět pomocí relačního operátoru ```„==“```
	- Např. ```d1 == d2```
- Převést na porovnání, zda je absolutní hodnota rozdílu dvou reálných čísel menší než absolutní chyba porovnání (ε – vhodně zvolená malá reálná konstanta)
	- ```Např. Math.abs(d1 - d2) < EPSILON```

