| ZER DAKIDAN: Funtzio batek sarreraren bat hartzen du eta emaitza bakar itzultzen du. Dagoeneko funtzio estandar hauek erabili ditut (denek math unitatea sartzea behar dute):
ZER IKASIKO DUDAN: Funtzioekin jarraituz rand() funtzio estandarra ikasiko dut eta hori erabiltzeko srand() funtzio estandarra ikasiko dut. Funtzioekin aurrera eginez, log(), log2(), log10(), exp() eta modf() funtzioak ikasiko ditut ere. |
Zerrenda honetan azpiprograma estandar batzuk deskribatzen dira, gogoratu #include <math.h> derrigorrezkoa dela:
double fabs(double x); // x zenbaki errealaren kopuruari dagokion balio absolutua kalkulatzen du double sin(double x); // x angeluaren (radianetan neurtuta) sinua itzultzen du double cos(double x); // x angeluaren (radianetan neurtuta) kosinua itzultzen du double tan(double x); // x angeluaren tangentea itzultzen du double asin(double x); // x angeluaren (-PI/2 eta +PI/2 tartekoa) arku sinua itzultzen du double acos(double x); // x angeluaren (0.0 eta +PI/2 tartekoa) arku kosinua itzultzen du double atan(double x); // x angeluaren (-PI/2 eta +PI/2 tartekoa) arku tangentea itzultzen du double pow(double x, double y); // x zenbaki errealaren kopurua ber y kalkulatzen du double sqrt(double x); // x erro karratuaren emaitza itzultzen du double exp(double x); // e ber x kalkulatzen du double log(double x); // logaritmo naturala itzultzen du double log2(double x); // bi oinarriko logaritmoa itzultzen du double log10(double x); // hamar oinarriko logaritmoa itzultzen du double fmod(double dbZatikizu, double dbZatitzai); // zatikizuna eta zatitzailea emanik, zatiketa osoaren hondarra itzultzen du double modf(double dbBalio, double *dbZatiOsoa); // dbBalio argumentua zati oso batean eta hamartar bestean bitan zatitzen du, eta bakoitzak argumentuaren zeinu bera du. Zati hamartarra da funtzioak itzultzen duena eta zati osoa double bat bezala gordetzen du dbZatiOsoa argumentuak adierazitako objektuanEta zerrenda honetan beste azpiprograma estandar batzuk deskribatzen dira, ez ahaztu #include <stdlib.h> derrigorrezkoa dela:
int abs(int x); // x zenbaki osoaren kopuruari dagokion balio absolutua kalkulatzen du
int rand(void); // zenbaki oso sasi-aleatoria kalkulatzen du 0tik RAND_MAX=2147483647 bitartean
// RAND_MAX inplementazioaren araberakoa da baina gutxienez RAND_MAX=32767
void srand(unsigned int iHazia); // iHazia argumentua sasi-ausazko zenbakien sekuentzia berri baterako hazi gisa
// erabiltzen du rand() funtzioak ondorengo deietan balioak itzultzeko
rand() funtzioak kopuru osoak itzultzen ditu, baina zenbaki erreal aleatorioak lor daitezke ere laster ikusiko dugun bezala.
rand() eta srand()
Zenbaki aleatorioak eskuratzeko rand() funtzio estandarra estandarra beharko dugu eta horrekin batera srand() funtzio estandarra ere.
Dado bat 3 aldiz jaurti dela simulatuko dugu. Dadoak 6 posibilitate ditu: 1, 2, 3, 4, 5 eta 6. Gure programak 3 jaurtiketa aleatorien emaitzak batuko ditu eta baturaren arabera mezu hau pantailaratuko du:
- 3 jaurtiketen baturak 13 edo gehiago balio badu, pantailaraketa Oso ondo izango da
- 3 jaurtiketen batura 10 eta 12 artekoa bada, pantailaraketa Nahiko ondo izango da
- 3 jaurtiketen batura 7 eta 9 artekoa bada, pantailaraketa Txarto izango da
- 3 jaurtiketen baturak 6 edo gutxiago balio badu, pantailaraketa Oso txarto izango da
Zenbaki osoekin jarraituz, kopuru aleatorioak 1 eta 6 artekoak izan ordez, 2 eta 4 bi mugen artekoak eskuratzeko horrela joko dugu:
/* Ariketa-19a1_FuntzioEstandarrak: zenbaki sasi-aleatorioak lortzen (kopuru osoak) */
// rand() ikasiko dugu, baina srand() funtzioarekin lotuta dago.
// Zenbaki aleatorioen segida lortzeko hazi bat behar da eta time() funtzioa erabiliko da NULL parametroarekin.
// rand() bitartez lortuko diren zenbaki aleatorioak kopuru osoak izango dira.
// Dado baten hiru jaurtiketa simulatuko da eta batura lortuz programak adieraziko digu
// jokaldia nolakoa izan den: oso txarra, txarra, ona ala oso ona.
#include <stdio.h> // printf() funtzioarako
#include <stdlib.h> // rand() eta srand() funtzioetarako
#include <math.h> // fmod() funtzioarako
#include <time.h> // time() funtzioarako
int main()
{
int iBatura = 0;
int iJaurtiketarenBalioa;
printf("\n");
printf("\n Dadoa hiru aldiz jaurti ondoren");
printf("\n -------------------------------");
srand(time(NULL)); // srand() zenbaki aleatorioak berriro hasiarazteko, hazia behar du
// Hazia, adibidez, time(NULL) funtzioa izan daiteke zeinek igarotako
// segundoak itzultzen ditu 1970-01-01 datatik hasita
iJaurtiketarenBalioa = rand(); // 0 eta RAND_MAX=32767 arteko balioa
iJaurtiketarenBalioa = iJaurtiketarenBalioa % 6 + 1; // 1 eta 6 arteko balioa
// edo iJaurtiketarenBalioa = fmod(iJaurtiketarenBalioa, 6) + 1; 1 eta 6 arteko balioa
printf("\n 1. jaurtiketan %d atera da", iJaurtiketarenBalioa);
iBatura = iBatura + iJaurtiketarenBalioa;
iJaurtiketarenBalioa = rand(); // 0 eta RAND_MAX=32767 arteko balioa
iJaurtiketarenBalioa = iJaurtiketarenBalioa % 6 + 1; // 1 eta 6 arteko balioa
// edo iJaurtiketarenBalioa = fmod(iJaurtiketarenBalioa, 6) + 1; 1 eta 6 arteko balioa
printf("\n 2. jaurtiketan %d atera da", iJaurtiketarenBalioa);
iBatura = iBatura + iJaurtiketarenBalioa;
iJaurtiketarenBalioa = rand(); // 0 eta RAND_MAX=32767 arteko balioa
iJaurtiketarenBalioa = iJaurtiketarenBalioa % 6 + 1; // 1 eta 6 arteko balioa
// edo iJaurtiketarenBalioa = fmod(iJaurtiketarenBalioa, 6) + 1; 1 eta 6 arteko balioa
printf("\n 3. jaurtiketan %d atera da", iJaurtiketarenBalioa);
iBatura = iBatura + iJaurtiketarenBalioa;
printf("\n");
switch(iBatura)
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6: printf("\n OSO TXARTO hiru jaurtiketen batura %d izan delako", iBatura);
break;
case 7:
case 8:
case 9: printf("\n TXARTO hiru jaurtiketen batura %d izan delako", iBatura);
break;
case 10:
case 11:
case 12: printf("\n NAHIKO ONDO hiru jaurtiketen batura %d izan delako", iBatura);
break;
default: printf("\n OSO ONDO hiru jaurtiketen batura %d izan delako", iBatura);
break;
}
printf("\n\n");
return 0;
}
rand() eta srand()
Zenbaki osoekin jarraituz, kopuru aleatorioak 1 eta 6 artekoak izan ordez, 2 eta 4 bi mugen artekoak eskuratzeko horrela joko dugu:
/* Ariketa-19a2_FuntzioEstandarrak: zenbaki sasi-aleatorioak lortzen (kopuru osoak) */
// Ariketa-19a1_FuntzioEstandarrak bezalakoa, baina 2 eta 4 mugen arteko kopuruekin.
#include <stdio.h> // printf() funtzioarako
#include <stdlib.h> // rand() eta srand() funtzioetarako
#include <time.h> // time() funtzioarako
#define BEHEMUGA 2
#define GOIMUGA 4
int main()
{
int iKont;
printf("\n");
printf("\n Manipulatutako dadoa %d eta %d artean", BEHEMUGA, GOIMUGA);
printf("\n -----------------------------------");
srand(time(NULL)); // zenbaki aleatorioak hasiarazteko
for (int iKont = 1; iKont <= 10; iKont++)
{
// random zenbakiak GOIMUGA=4 eta BEHEMUGA=2 artekoak (biak barne)
// rand()%(GOIMUGA-BEHEMUGA+1) rand()%3 (0, 1 edo 2)
// rand()%(GOIMUGA-BEHEMUGA+1)+BEHEMUGA rand()%3+2 (2, 3 edo 4)
iJaurtiketarenBalioa = rand() % (GOIMUGA - BEHEMUGA + 1) + BEHEMUGA;
printf("\n %5d. jaurtiketan %d atera da", iKont, iJaurtiketarenBalioa);
}
printf("\n\n");
return 0;
}
Manipulatu den dadoaren programa honetan for agindu errepikakorra agertzen da. Aurrerago azalduko da modu xehean, baina orain jakin dezagun for aginduak balio duela ekintzak errepikatzeko kopuru jakin batean, adibidean ekinza 10 aldiz errepikatzen da.
rand() eta srand()
Zenbaki errealekin lan eginez, balio aleatorioak lortzen dituen programa idatziko dugu. Ikusi dugun rand() funtzioak 0 eta RAND_MAX=32767 arteko kopuru osoa itzultzen duenez kode gehiago gehituko zaio programari zenbaki errealekin lan egiteko, zatiketa bat eta datu-mota beharketa bat. Honelaxe:
fZenbakia = (float)rand()/RAND_MAX; // 0.0 eta 0.999 arteko balioa
printf("fZenbakia = %f\n", fZenbakia);
Programa osoa hemen. Non lehen for aginduan 15 iterazio egiten diren 0 eta RAND_MAX=32767 arteko zenbaki sasi aleatorio osoak lortuz, eta bigarren for aginduan beste 15 iterazio egiten diren auzazko zenbaki sasi aleatorio osoak 0.0 eta 0.999 esparrura mugatuz:
/* Ariketa-19b1_FuntzioEstandarrak: zenbaki sasi-aleatorioak lortzen (kopuru errealak) */
// rand() ikasiko dugu, baina srand() funtzioarekin lotuta dago.
// Zenbaki aleatorioen segida lortzeko hazi bat behar da eta time() funtzioa erabiliko da
// NULL parametroarekin zeinek igarotako segundoak itzultzen ditu 1970-01-01 datatik hasita.
// rand() bitartez lortuko diren zenbaki aleatorioak 0 eta RAND_MAX=32767 arteko kopuru
// osoak izango dira. Zenbaki erreala lortzeko zatiketa+beharketa egin daiteke.
#include <stdio.h> // printf() funtzioarako
#include <stdlib.h> // rand() eta srand() funtzioetarako
#include <time.h> // time() funtzioarako
#define BEHEMUGA 2
#define GOIMUGA 4
int main()
{
float fZenbakia;
int iKopurua;
printf("\n");
srand(time(NULL)); // srand() zenbaki aleatorioak berriro hasiarazteko, hazia behar du
// Hazia, adibidez, time(NULL) funtzioa izan daiteke zeinek igarotako
// segundoak itzultzen ditu 1970-01-01 datatik hasita
iKopurua = rand();
printf("Zenbaki sasi aleatorioen hazia %d da\n", iKopurua);
printf("\n \t 0 eta RAND_MAX=%d artekoak", RAND_MAX);
printf("\n \t -----------------------------\n");
for (int iKont = 1; iKont <= 15; iKont++)
{
iKopurua = rand(); // 0 eta RAND_MAX=32767 arteko kopuru osoa
printf("%10d \t iKopurua = %d\n", iKont, iKopurua);
}
printf("\n \t 0.0 eta 0.999 arteko balioak");
printf("\n \t ----------------------------\n");
for (int iKont = 1; iKont <= 15; iKont++)
{
fZenbakia = (float)rand()/RAND_MAX; // 0.0 eta 0.999 arteko balio erreala
printf("%10d \t fZenbakia = %f\n", iKont, fZenbakia);
}
printf("\n");
return 0;
}
rand() eta srand()
Zenbaki errealekin lan eginez, balio aleatorioak lortzen dituen programa idatziko dugu. Ikusi dugun rand() funtzioak kopuru osoa itzultzen duenez kode gehiago gehituko zaio programari zenbaki errealekin lan egiteko, hauxe:
#define BEHEMUGA1 70.5 // abiadura aleatorioaren minimoa
#define GOIMUGA1 100.6 // abiadura aleatorioaren maximoa
fAbiadura = ((float)rand()/(float)(RAND_MAX)) * (GOIMUGA1-BEHEMUGA1); // 0.0 eta 0.999 artekoa bider (GOIMUGA1-BEHEMUGA1)
printf("\n %10f (0.0 eta %.1f artekoa)", fAbiadura, GOIMUGA1-BEHEMUGA1); // 0.0 eta 30.1 artekoa
fAbiadura= fAbiadura + BEHEMUGA1;
printf("\n %10f (%.1f eta %.1f artekoa)", fAbiadura, BEHEMUGA1, GOIMUGA1); // 70.5 eta 100.6 artekoa
Auto baten abiadura adierazten duen zenbaki erreal bat aleatorioki lortuko da, baina zenbaki aleatorio horren balioa bi mugen artekoa izan beharko da: behemuga 70.5 km/h eta goimuga 100.6 km/h.
Auto horren denbora adierazten duen zenbaki erreal bat aleatorioki lortuko da, eta bigarren zenbaki aleatorio horren balioa bi mugen artekoa izan beharko da ere: behemuga 0.5 segundo eta goimuga 2.0 segundo.
Aurreko bi datuekin (abiadura eta denbora) distantziaren kalkulua burutuko da. Eskatzen den programaren exekuzio-adibide bat jarraian erakusten da:
![]() |
Eta hemen azalpena:
![]() |
Goiko irudian Ariketa-19b2_FuntzioEstandarrak programaren bigarren for aginduaren pantailaraketak iruzkindu dira, adibideko 1.961043 denbora aleatorioa (0.5 segundo eta 2.0 segundo artekoa) lau urratsetan lortzen da:
- rand() funtzioa aplikatu auzazko balio osoa eskuratzeko (31916 adibidean)
- Lortutako balio osoa normalizatu 0.0 eta 0.999 esparrura (0.974029 adibidean)
- Balio erreala eskalatu (GOIMUGA-BEHEMUGA2) esparrura (1.461043 adibidean)
- Aurreko urratsean lortutakoari BEHEMUGA2 oinarria gehitu (1.961043 adibidean)
rand() eta srand()
Demagun azterketa baten notak auzaz lortu nahi direla, jakinik kalifikaziorik txikiena 0.00 dela eta kalifikaziorik handiena 9.99 dela. Nahiz eta notak zenbaki errealak diren, balio aleatorioak lortzean 0 eta 9 arteko kopuru osoak erabiliko ditugu:
/* Ariketa-19b3_FuntzioEstandarrak: zenbaki sasi-aleatorioak lortzen (kopuru errealak) */
// rand() ikasiko dugu, baina srand() funtzioarekin lotuta dago.
// Zenbaki aleatorioen segida lortzeko hazi bat behar da eta time() funtzioa erabiliko da
// NULL parametroarekin zeinek igarotako segundoak itzultzen ditu 1970-01-01 datatik hasita.
// rand() bitartez lortuko diren zenbaki aleatorioak 0 eta RAND_MAX=32767 arteko kopuru
// osoak izango dira. Hamartar bakarra duen zenbaki erreala lortzeko osoekin lan egin daiteke.
// Demagun azterketa baten nota adierazten duten 0.00 eta 9.99 arteko hainbat zenbaki erreal
// ditugula eta nota guztien batezbesteko aritmetikoa kalkulatu nahi dela.
#include <stdio.h> // printf() funtzioarako
#include <stdlib.h> // rand() eta srand() funtzioetarako
#include <time.h> // time() funtzioarako
#define iZENBAT 20
int main()
{
float fNota;
int iUnitatea;
int iHamarrekoa;
int iEhunekoa;
float fBatukaria = 0.0;
srand(time(NULL)); // srand() zenbaki aleatorioak berriro hasiarazteko, hazia behar du
// Hazia, adibidez, time(NULL) funtzioa izan daiteke zeinek igarotako
// segundoak itzultzen ditu 1970-01-01 datatik hasita
printf("\n");
printf(" %d kalifikazio: 0.00 eta 9.99 arteko balio sasi-aleatorioak\n", iZENBAT);
printf(" -----------------------------------------------------------\n");
for (int iKont = 1; iKont <= iZENBAT; iKont++)
{
iUnitatea = rand() % 10; // 0 eta 9 arteko balioak
iHamarrekoa = rand() % 10; // 0 eta 9 arteko balioak
iEhunekoa = rand() % 10; // 0 eta 9 arteko balioak
fNota = iUnitatea + 0.1*iHamarrekoa + 0.01*iEhunekoa;
fBatukaria = fBatukaria + fNota;
printf("%4d iUnitatea=%d iHamarrekoa=%d iEhunekoa=%d fNota=%.2f\n", iKont, iUnitatea, iHamarrekoa, iEhunekoa, fNota);
}
printf(" -----------------------------------------------------------\n");
printf("\n Bataztesteko aritmetikoa %.2f da\n", fBatukaria/iZENBAT);
printf("\n");
return 0;
}
log() eta exp()
5.2x=7.9 bezalako ekuazio esponentziala ebazteko logaritmoa erabil behar da, hots, logaritmo nepertarra kalkulatzen duen log() funtzio estandarra. Modu beretsuan, 7.13.4=x bezalako ekuazioak ebazteko exp() funtzio estandarra aplika dezakegu.
Eskatzen den programaren exekuzio-adibide bat ikusi:
|
|
|
log(), log2(), log10() eta beste oinarriko logaritmoak
Zenbaki errealekin lan eginez, balio positibo bat teklatuz irakurri eta programak zenbakiaren logaritmo hamartarra kalkula dezala log10() funtzio estandarra erabili gabe. Logaritmo bitarra eskuratzeko funtzio estandarrik ez dagoenez, logaritmo nepertarraren funtzioa aplikatu beharko da formula hauen arabera:
exp() eta beste oinarriko potentziak
Zenbaki errealekin lan eginez, exponentea izango den balio positibo edo negatibo bat teklatuz irakurri (adibidez Z=4.001), ondoren oinarria izango den balio positibo edo negatibo bat teklatuz irakurri (adibidez Y=2.001). Programak datuen potentzia kalkula dezala (emaitza X=2.0014.001). Horrelako lana burutzeko adibidez pow()funtzio estandarra izan arren, logaritmo nepertarraren log() funtzioa eta e zenbakiari dagokion exp() potentziaren funtzioa aplikatuko dira esleipen hau eginez:
Goiko esleipenaren justifikazioa jarraian ematen da:
Z datua den zenbaki erreala (exponentea)
Y datua den zenbaki erreala (oinarria)
X lortu nahi den potentzia
X = Y^Z logaritmo nepertarrak hartuz:
log(X) = log(Y^Z) ---> log(X) = Z·log(Y)
log(X) = Z·log(Y)
exp() funtzioa aplikatuz:
log(X) = Z·log(Y)
exp(log(X)) = exp(Z·log(Y))
X = exp(Z·log(Y))
fmod() eta modf()
Funtzio guztiz desberdinak dira, baina izenak oso antzekoak direlako nahasteko arriskua dago. Funtzio biek bi parametro dituzte, baina parametroen esanahia eta funtzioaren emaitzak oso bestelakoak dira.
fmod() funtzioaren helburua da zatiketa osoaren hondarra itzultzea. Bere ohiko deia honelako zerbait da, non parametroen datu-motak float izan daitezke eta int izan daizteke.
dbHondarra = fmod(dbZatikizuna, dbZatitzailea);
modf() funtzioaren helburua da zenbaki erreal baten zati hamartarra eta zati osoa eskuratzea, kasu honetan datua bakarra da (zenbaki errealaren balioa) eta emaitzak bi dira (zati hamartarra eta zati osoa), hona hemen modf() funtzioaren balizko dei bat:
Ikusten denez bigarren parametroa helbide bat da, zati osoa gordeko duen zenbaki errealaren helbidea hain zuzen ere. Ikusten da ere zati hamartarra modf() funtzioak itzultzen duen emaitza dela.
Hauxe izan daiteke eskatzen den programaren irteera:
asin(), acos() eta atan()
Zenbaki errealekin lan eginez, angelu baten sinua adierazten duen balio bat teklatuz irakurri (-1.0 eta +1.0 arteko balioa) eta programak angelua lortuko du radianetan:
Gauza bera egin daiteke datua angeluaren kosinua baldin bada acos funtzioa aplikatuz. Edozein kasutan, asin eta acos funtzio estandarrak erabil ahal izateko math liburutegia kargatu beharko da (berdin atan funtzioarekin, math liburutegia beharrezkoa da).
Hemen asin funtzioaren grafikoa (irudiaren gainean klik egin balioak emateko):
Hauxe izan daiteke eskatzen den programaren irteera:
|












iruzkinik ez:
Argitaratu iruzkina