11. diel - Matematické funkcie v jazyku C
V minulej lekcii, Podmienky v C druhýkrát - ternárne výraz a propadávací switch , sme sa venovali ďalšie syntax podmienok.
V minulej lekcii, Podmienky v C druhýkrát - ternárne výraz a propadávací switch , sme si predstavili viacrozmerné pole. V
dnešnom tutoriále kurze základov jazyka C sa pozrieme na štandardné
knižnicu math.h
. Tá poskytuje veľké množstvo funkcií pre
riešenie obvyklých matematických problémov, tie najdôležitejšie z nich si
uvedieme.
Fmin (), fmax (), fdim ()
Začnime s tým jednoduchším Všetky funkcie prijímajú ako parameter dve čísla typu
double
. Funkcia fmin()
vráti to menšie, funkcia
fmax()
to väčší z nich. Funkcia fdim()
vráti
x - y
, ak je x > y
. V ostatných prípadoch vracia
0
.
Round (), ceil (), floor () a TRUNC ()
Všetky funkcie sa týkajú zaokrúhľovania a prijímajú parametre typu
double
. Návratová hodnota pre všetky funkcie takisto typu
double
. round()
vracia zaokrúhlené
číslo tak, ako to poznáme zo školy (od 0.5
nahor, inak dole).
ceil()
zaokrúhli vždy hore a floor()
vždy dolu.
trunc()
nezaokrúhľujú, iba odtrhne desatinnú časť.
round()
budeme určite potrebovať často, ďalšie funkcie som
často použil napríklad keď som zisťoval počet položiek na stránke (napr.
nejaké tabuľky v konzole). Ak máme 33
položiek a na stránke
ich je vypísané 10
, budú matematicky zaberať 3.3
stránok. Výsledok musíme zaokrúhliť nahor, pretože v reále stránky budú
samozrejme 4
.
Ak vás napadlo, že floor()
a trunc()
robia to
isté, správajú sa inak u záporných čísel. Vtedy floor()
zaokrúhli na číslo viac do mínusu, trunc()
zaokrúhli vždy k
nule.
Zaokrúhlenie desatinného čísla a jeho uloženie do premennej typu
int
teda vykonáme nasledujúcim spôsobom:
double d = 2.72; int a = (int)round(d);
Pretypovanie na int
je nutné, pretože round()
vracia síce celé číslo, ale stále uložené v type double
a to
kvôli tomu, aby všetky matematické funkcie mali rovnaké rozhranie. Preto
nebudem u zvyšných funkcií typy uvádzať - vždy bude
double
.
Abs () a signbit ()
abs()
vráti absolútnu hodnotu parametra a
signbit()
vráti 1
, ak je číslo záporné, vo
zvyšných prípadoch vracia 0
. Funkcia signbit()
nie
je podporovaná vo všetkých kompilerech, preto je možné, že ju nemusíte
mať dostupnú.
Sin (), cos (), tan ()
Klasické goniometrické funkcie prijímajú ako parameter uhol v
radiánoch, nie v stupňoch. Pre konverziu stupňov na radiány
stupňa vynásobíme hodnotou * (M_PI / 180)
.
ACOS (), asin (), atan ()
Opäť klasické cyklometrické funkcie (arkus funkcie), ktoré podľa
hodnoty goniometrické funkcie vráti daný uhol. Jedná sa o inverzné funkcie
k sin()
, cos()
a tan()
. Parametrom je
hodnota uhla, výstupom uhol v radiánoch. Pokiaľ si prajeme mať uhol v
stupňoch, vynásobíme radiány hodnotou * (180 / M_PI)
.
Pow () a sqrt ()
pow()
prijíma dva parametre, prvý je základ mocniny a druhý
exponent. Ak by sme teda chceli vypočítať napr. 2 3, kód by bol
nasledujúci:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char** argv)
{
double vysledek = pow(2,3);
printf("%lf", vysledek);
return (EXIT_SUCCESS);
}
sqrt()
je skratka zo Square root a vracia druhú odmocninu z
daného čísla.
Exp (), log (), log10 ()
Funkcia exp()
vracia Eulerovo Číslo, umocnené na daný
exponent. Funkcia log()
vracia prirodzený logaritmus daného
čísla. log10()
vracia dekadický logaritmus daného čísla.
V zozname metód nápadne chýba ľubovoľná odmocnina. My ju však dokážeme spočítať aj na základe funkcií, ktoré knižnica poskytuje.
Vieme, že platí: 3. odm. z 8 = 8^(1/3)
. Môžeme teda
napísať:
{C_IMPORTS}
#include <math.h>
{C_MAIN_BLOCK}
double vysledek = pow(8, (1.0/3.0));
printf("%lf", vysledek);
{/C_MAIN_BLOCK}
Je veľmi dôležité, aby sme pri delení napísali aspoň jedno číslo s
desatinnou bodkou, inak bude C predpokladať celočíselné delenie a výsledkom
by v tomto prípade bolo 8^0 = 1
.
Delenie
Programovacie jazyky sa často odlišujú tým, ako v nich funguje delení čísel. Túto problematiku je nutné dobre poznať, aby ste neboli prekvapení. Napíšme si jednoduchý program:
{C_CONSOLE}
int a = 5 / 2;
double b = 5 / 2;
double c = 5.0 / 2;
double d = 5 / 2.0;
double e = 5.0 / 2.0;
int f = 5 / 2.0;
printf("a=%d b=%f c=%f d=%f e=%f f=%d", a, b, c, d, e, f);
{/C_CONSOLE}
V kóde niekoľkokrát delíme 5 / 2
, čo je matematicky
2.5
. Iste ale tušíte, že výsledok nebude vo všetkých
prípadoch rovnaký. Trúfnete si tipnúť, čo kedy vyjde? Skúste to
Konzolová aplikácia
a=2 b=2.000000 c=2.500000 d=2.500000 e=2.500000 f=2
Vidíme, že výsledok delenie je niekedy celočíselný a niekedy reálny. Pritom nezáleží iba na dátovom type premenné, do ktorej výsledok ukladáme, ale na dátovom type čísel, ktoré delíme. Ak je jedno z čísel desatinné, je výsledok vždy desatinné číslo. 2 celé čísla vždy vráti celé číslo, dajte si na to pozor, napr. Keď budete počítať priemer. Pre desatinný výsledok je nutné aspoň jednu premennú pretypovať na desatinné číslo.
int soucet = 10; int pocet = 4; double prumer = (double)soucet / (double)pocet;
Pozn .: Napr. v jazyku PHP je výsledok delenie vždy desatinný. Až budete deliť v inom programovacom jazyku ako je C, zistite si, ako delenie funguje ako ho použijete.
Zvyšok po delení
V našich aplikáciách môžeme často potrebovať zvyšok po delení (tzv.
Modulo). U nášho príkladu 5 / 2
je celočíselný výsledok
2
a modulo 1
(zvyšok). Modulo sa často používa pre
zistenie, či je číslo párne (zvyšok po delení 2
je
0
) alebo keď chcete zistiť odchýlku vašej pozície od nejakej
štvorcovej siete.
V céčku a všeobecne v céčkových jazykoch (tzv. C-like jazyky)
zapíšeme modulo ako %
:
{C_CONSOLE}
printf("Zvyšok po delení 5/2 je %d", 5 % 2);
{/C_CONSOLE}
Tak to by sme mali. V budúcej lekcii, Riešené úlohy k 10. a 11. lekcii Céčka , si uvedieme funkcie, ktoré sú veľmi dôležité - pomôžu nám rozdeliť program do viacerých logických celkov.
V nasledujúcom cvičení, Riešené úlohy k 10. a 11. lekcii Céčka, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.