2025(e)ko otsailaren 12(a), asteazkena

3. jarduera (II) | Errusiar Biderketaren Metodoa prestatzen

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 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:

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).

Bilatzen dugu iIterazioak aldagaiaren balioa fMailak aldagaiaren zati osoa izango da. Beraz:

fMailak = log2(iZenbakia)
iIterazioak = (int)fMailak
iIterazioak = (int)log2(iZenbakia)

Hona hemen eskatzen den programaren balizko irteera bat, non iIterazioak kalkulatu ondoren, zatirik interesgarriena  for (iKont=1; iKont<=iIterazioak; iKont++)  aginduarena den:


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;
} 


  • 3a-Jarduera_ErrusiarBiderketa_1.cbp | main.c       [metodoa zertan den]
  • 3a-Jarduera_ErrusiarBiderketa_2.cbp | main.c       [metodoa zertan den]
  • 3a-Jarduera_ErrusiarBiderketa_3.cbp | main.c       [metodoa zertan den]
  • 3b-Jarduera_ErrusiarBiderketa.cbp | main.c           [metodoa prestatzen]
  • 3c-Jarduera_ErrusiarBiderketa_1.cbp | main.c       [metodoa programatzen]
  • 3c-Jarduera_ErrusiarBiderketa_2.cbp | main.c       [metodoa programatzen]


 

iruzkinik ez:

Argitaratu iruzkina