| ZER DAKIDAN: Hainbat funtzio estandar ikasi dut eta for agindua ikasi dut ere. ZER IKASIKO DUDAN: Agindu errepikakor habiaraturkin sakondu aurretik, for agindu isolatua erabiliko dut jarduera handiago batean. |
Dakigunez, artikulu honekin lotuta daude bi artikulu hauek:
- 3. jarduera (I) | Errusiar Biderketaren Metodoa zertan den
- 3. jarduera (III) | Errusiar Biderketaren Metodoa programatzen
3. jarduera (I) | Errusiar Biderketaren Metodoa zertan den izenburuko artikulua gogoratuz, ariketa honetan bi zenbiren arteko biderkadura kalkulatzen duen programari hasiera emango diogu.
Errusiar Biderketaren Metodoa prestatzen artikulu honen helbura da zehaztea zenbat maila izango diren osoa den zenbaki jakin baterako. Datua: iZenbakia zenbaki osoa. Inkognita: iIterazioak zenbaki osoa.
Datua den iZenbakia zenbaki oso bat irakurriko dugu (0 eta 15000 artekoa). Adibidez emandako datua 36 bada, eskatzen den pantailaraketaren zatirik mamitsuena hau da: Erdiak Dobleak
------ -------
1. maila 18 72
2. maila 9 144
3. maila 4 288
4. maila 2 576
5. maila 1 1152
iZenbakia aldagaian 36 hartu bada, goiko taularen mailak 5 izango dira, zenbakiaren balioa eta mailen kopurua estuki lotuta daude 2 konstantearen bitartez (horri esker erdiak eta dobleak lortzen baitira). Maila kopurua iterazioen kopurua izango da eta iIterazioak aldagaian gordetzen da, baina iIterazioak ezagutzeko hauxe da kalkulua non fMailak zenbaki erreal bat den:
Bilatzen dugu iIterazioak aldagaiaren balioa fMailak aldagaiaren zati osoa izango da. Beraz:2fMailak = iZenbakia
log2(2fMailak) = log2(iZenbakia)
fMailak·log2(2) = log2(iZenbakia)
fMailak·1 = log2(iZenbakia)
fMailak = log2(iZenbakia) non log2 logaritmo bitarraren funtzioa den (ikusi blogeko Ariketa 19 | Zenbakien funtzio estandarrak artikuluan ematen diren (c) eta (d) programak).
Hona hemen eskatzen den programaren balizko irteera bat, non iIterazioak kalkulatu ondoren, zatirik interesgarriena for (iKont=1; iKont<=iIterazioak; iKont++) aginduarena den:fMailak = log2(iZenbakia)
iIterazioak = (int)fMailak
iIterazioak = (int)log2(iZenbakia)
Ikusi ere long datu-motarekin lan eginez dobleak kalkulatzean MAX_LONG konstantea berehala gainditzen dela. Horregatik, programaren azken bertsioan dobleak gordetzen duen aldagaia float bezala deklaratuko dugu.
/* 3b-Jarduera_ErrusiarBiderketa: for aginduaren adibidea. */
// Zenbaki osoekin lan eginez, iZenbakia teklatuz irakurri
// ziurtatuz datua 64 edo handiagoa dela (adibidez 65), eta
// irakurritako datuaren lehen 4 erdiak eta lehen 4 dobleak
// pantailan idatzi. Datuaren balio maximoa 15000 izango da.
#include <stdio.h> // printf() eta scanf() funtzioetarako
#include <math.h> // log2() funtzioarako
#define GUREMINIMOA 64
#define GUREMAXIMOA 15000
#define ITERAZIOKOPURUA 4
int main()
{
int iZenbakia, iKont;
int iErdia, iIterazioak;
long lDoblea;
printf("\n");
printf("\n Kopuru osoko eta positiboekin lan egingo da");
printf("\n -------------------------------------------\n");
printf("\n [%d, %d] arteko zenbaki osoa eman eta iterazio kopuru", GUREMINIMOA, GUREMAXIMOA);
printf("\n desberdineko bere erdiak eta dobleak pantailaratuko dira.\n\n");
do
{
printf(" Biderkagai bat adierazten duen zenbaki osokoa eman (789 adibidez): ");
scanf("%d", &iZenbakia);
if (iZenbakia < GUREMINIMOA)
printf(" Datua %d edo handiago izango da! \n", GUREMINIMOA);
if (iZenbakia > GUREMAXIMOA)
printf(" Datua %d edo txikiago izango da! \n", GUREMAXIMOA);
} while (iZenbakia < GUREMINIMOA || iZenbakia > GUREMAXIMOA);
printf("\n \t \t \tErdiak\tDobleak");
printf("\n \t \t \t------\t-------");
iErdia = iZenbakia;
lDoblea = iZenbakia;
for (iKont=1; iKont<=ITERAZIOKOPURUA; iKont++)
{
iErdia = iErdia / 2;
lDoblea = lDoblea*2;
printf("\n \t %2d. iterazioa \t %5d \t%ld", iKont, iErdia, lDoblea);
}
printf("\n\n Ikusi %d datuarekin, erdiaren azken balioa %d dela, baina...", iZenbakia, iErdia);
printf("\n Zenbat iterazio behar dira %d-rekin azken erdia 1 izan dadin?", iZenbakia);
printf("\n Erantzuna: log2(iZenbakia) iterazio, %d-rako %d iterazio.", iZenbakia, (int)log2(iZenbakia));
printf("\n");
printf("\n \t \t \tErdiak\tDobleak");
printf("\n \t \t \t------\t-------");
iErdia = iZenbakia;
lDoblea = iZenbakia;
iIterazioak = (int)log2(iZenbakia);
for (iKont=1; iKont<=iIterazioak; iKont++)
{
iErdia = iErdia / 2;
lDoblea = lDoblea*2;
printf("\n \t %2d. iterazioa \t %5d \t%ld", iKont, iErdia, lDoblea);
}
printf("\n\n Zer gertatzen da %d datuarekin %d iterazio egin ordez %d iterazio egitean?", iZenbakia, iIterazioak, iIterazioak+3);
printf("\n");
printf("\n \t \t \tErdiak\tDobleak");
printf("\n \t \t \t------\t-------");
iErdia = iZenbakia;
lDoblea = iZenbakia;
iIterazioak = (int)log2(iZenbakia)+3;
for (iKont=1; iKont<=iIterazioak; iKont++)
{
iErdia = iErdia / 2;
lDoblea = lDoblea*2;
printf("\n \t %2d. iterazioa \t %5d \t%ld", iKont, iErdia, lDoblea);
}
iIterazioak = (int)log2(GUREMAXIMOA);
printf("\n\n Eta GUREMAXIMOA=%d datuarekin %d iterazio egin ordez %d iterazio egitean?", GUREMAXIMOA, iIterazioak, iIterazioak+7);
printf("\n");
printf("\n \t \t \tErdiak\tDobleak");
printf("\n \t \t \t------\t-------");
iErdia = GUREMAXIMOA;
lDoblea = GUREMAXIMOA;
iIterazioak = (int)log2(GUREMAXIMOA)+7;
for (iKont=1; iKont<=iIterazioak; iKont++)
{
iErdia = iErdia / 2;
lDoblea = lDoblea*2;
printf("\n \t %2d. iterazioa \t %5d \t%ld", iKont, iErdia, lDoblea);
}
printf("\n\n");
return 0;
}
|

iruzkinik ez:
Argitaratu iruzkina