ELEKTRONINĖS KNYGOS

tus0.gif (69 bytes)

Gintautas GRIGAS
PROGRAMAVIMAS PASKALIU

4. DISKRETIEJI DUOMENŲ TIPAI IR JŲ VALDOMI VEIKSMAI
Gyvenime susiduriame su dviejų tipų dydžiais: tolydžiaisiais ir diskrečiaisiais. Kompiuterio prigimtis yra diskreti arba dar vadinama kitaip – skaitmeninė. Kiekvieno jo elemento būseną galima apibūdinti diskrečiuoju dydžiu, pavyzdžiui, sveikuoju skaičiumi. Skaičiavimo technika lemia ir tai, kad gyvenime vis daugiau plinta diskretieji (skaitmeniniai) prietaisai: skaitmeninės svarstyklės, skaitmeniniai garso įrašai, skaitmeninė fotografija ir t.t. Dėl to natūralu, kad daugelio uždavinių pradiniai duomenys ir rezultatai yra diskretieji duomenys.

Programavime diskretieji duomenys naudojami dar ir veiksmams valdyti, panašiai, kaip ir loginiai duomenys.

4.1. Vardiniai duomenų tipai – diskrečiųjų duomenų tipų pagrindas

Uždaviniuose dažnai būna duomenų, kurie gali turėti nedaug galimų reikšmių. Pavyzdžiui, uždavinyje, kuriame operuojama su Mėnulio fazėmis, reikalingas duomuo, galintis turėti keturias reikšmes: jaunatis, priešpilnis, pilnatis, delčia. Fazes iš bėdos galima žymėti (koduoti) skaičiais (pavyzdžiui, 1, 2, 3, 4). Tačiau tai nepatogu ir nevaizdu – reikia prisiminti, kuris skaičius kurią fazę reiškia. Todėl programoje fazes būtų fazes geriau vadinti tikraisiais jų vardais, taip, kaip ir gyvenime.

Panašių duomenų pasitaiko dažnai. Pavyzdžiui, pagrindinė spalva – mėlyna, geltona, raudona; mokyklos tipas – pradinė, pagrindinė, vidurinė, gimnazija; pasaulio šalis – šiaurė, rytai, pietūs, vakarai; trumpas atsakymas anketoje – taip, ne, nežinau; septynios savaitės dienos ir t.t. Būtų patogu, kad programavimo kalboje kiekvienam aptartam atvejui rastume tinkamą duomenų rūšį, programavime vadinamą duomenų tipu. Tačiau, kad ir kiek būtų duomenų tipų, vistiek jų neužtektų, nes įvairių uždavinių programose beveik visada yra tik tiems uždaviniams būdingų duomenų. Todėl užuot gausinus tipų skaičių, einama kitu keliu – leidžiama pačiam programuotojui aprašyti naujus jam reikalingus tipus.

Aprašysime paminėtus duomenų tipus.

type fazė = (jaunatis, priešpilnis, pilnatis, delčia);
        spalva = (mėlyna, geltona, raudona);
        mokykla = (pradinė, pagrindinė, vidurinė, gimnazija);
        pasšalis = (šiaurė, rytai, pietūs, vakarai);
        atsakymas = (taip, ne, nežinau);
        savd = (pirm, antr, treč, ketv, penk, šešt, sekm);

Visų tipų aprašas pradedamos žodžiu type, o kiekvieno tipo aprašas – naujai aprašomo duomenų tipo vardu.

Skliaustuose išvardijamos aprašomiems duomenų tipams priklausančių reikšmių (konstantų) vardai. Todėl tokie tipai vadinami vardiniais.

Aprašysime keletą kintamųjų, vartodami ką tik aprašytus vardinius duomenų tipus.

var pieštukas, rašalas: spalva;
      rodyklė, kryptis: pasšalis;
      a, b, c: mokykla;
      šiandien, rytoj: savd;

Vardinis tipas iš tikrųjų yra ne vienas duomenų tipas, o daug skirtingų tipų – tiek, kiek jų aprašyta programoje. (Čia aprašėme net šešis tipus). Tai vardinių duomenų tipų šeima.

Programuotojo aprašyti duomenų tipų vardai (pvz., pasšalis, mokykla, savd) panaudojami analogiškai, kaip ir standartiniai (pvz., integer, boolean).

Kintamajam galima priskirti tik jo apraše nurodyto tipo reikšmes, pavyzdžiui:

pieštukas := geltona;
rašalas := mėlyna;
rašalas := pieštukas;
rodyklė := pietūs;
a := treč

Tačiau neleistina priskirti kito tipo reikšmes:

rodyklė := raudona;
a := pieštukas

Daugeliui duomenų tipų būdinga jų reikšmių tvarka. Surikiuotos yra, pavyzdžiui, savaitės dienos: trečiadienis eina po antradienio ir prieš ketvirtadienį. Dėl to vardiniai duomenų tipai laikomi sutvarkytais: laikoma, kad jų reikšmės surikiuotos tokia tvarka, kaip jų vardai pateikti duomenų tipo apraše. Todėl visų vardinių duomenų tipų reikšmes galima palyginti (atlikti operacijas <, <=, <>, > ir >=). Be to, galima atlikti dvi standartines funkcijas succ ir pred.

Funkcijos succ reikšmė yra to paties vardinio tipo reikšmė, einanti po duotosios reikšmės, pavyzdžiui:

succ(ne) = nežinau,
succ(šeš) = sekm

Funkcijos pred reikšmė yra to paties tipo reikšmė, einanti prieš duotąją reikšmę, pavyzdžiui:

pred(rytai) = šiaurė,
pred(šešt) = penk

Atliekant lyginimo operacijas, laikoma, kad reikšmių eilė sutampa su jų konstantų vardų eile tipo apraše. Pavyzdžiui:

pirm < antr   ->   true,
pirm <= antr   ->   true,
pirm < antr    ->   false,
šiaurė < rytai    ->   true,
priešpilnis < pilnatis   ->   true.

Vardinių duomenų tipų reikšmių Paskalio kalboje negalima nei skaityti, nei rašyti. Tai galima laikyti Paskalio kalbos arba vardinių duomenų tipų trūkumu. Tačiau šis trūkumas nėra programavimo kalbų projektuotojų klaida. Tai savybė, išplaukianti iš pačių vardinių duomenų tipų aprašymo būdo. Jie aprašomi programos viduje. O viskas, kas aprašyta programoje, nėra žinoma už jos ribų, t.y., prieš pradedant programai darbą arba jį baigus. Ta pati reikšmė vienoje programoje gali būti pavadinta vienu vardu, kitoje – kitu. Kas kita yra visuotinai priimtus žymenis turinčios standartinių duomenų tipų, pavyzdžiui, skaičių, reikšmės. Skaičiai visose programose žymimi vienodai. Dėl to vardiniai duomenų tipai dažniau vartojami didesnėse programose, kuriose apsimoka turėti daug įvairių vidinių duomenų tipų.

Diskretieji duomenų tipai ir vardiniai duomenų tipai. Programavime duomenų tipai klasifikuojami įvairiai. Viena iš galimų klasifikacijų: diskretieji ir tolydieji.

Diskretieji duomenų tipai yra tokie, kurie turi baigtinį reikšmių skaičių ir tas reikšmes galima surikiuoti. Su jais atliekamos tik tos operacijos, kurias nusako reikšmių rikiavimas: lyginimo operacijos ir funkcijos succ ir pred. Ir viskas.

Paskalio kalboje vardinis duomenų tipas laikomas visų kitų diskrečiųjų duomenų tipų pagrindu. Visi kiti diskretieji duomenų tipai kildinami iš vardinio duomenų tipo. Laikoma, kad jie visi iš vardinio duomenų tipo paveldi lyginimo operacijos ir funkcijos succ ir pred ir turi dar naujų savų operacijų

Diskrečiųjų duomenų tipų grupei priklauso sveikieji skaičiai, loginis bei simbolinis duomenų tipas. Loginio duomenų tipo reikšmės žymimos vardais false ir true, visai taip kaip ir vardinio duomenų tipo reikšmės. Laikoma, kad reikšmės surikiuotos tokia pat tvarka kaip ir ką tik jas išvardinome: false, true.

Sveikieji skaičiai turi savus konstantų žymenis. Galima laikyti, kad skaičiai (pvz., -123, 4545) yra tikriniai, t.y. neaprašomi sveikojo duomenų tipo konstantų vardai.

Simbolinio tipo reikšmės – simboliai taip pat yra šio duomenų tipo konstantų tikriniai vardai.

Tolydžiųjų duomenų tipų grupei priklauso tik realieji skaičiai.

Programavime diskretieji duomenų tipai vaidina svarbų vaidmenį dėl to, kad jų reikšmės gali valdyti veiksmų atlikimo tvarką. Apie tai kalbėsime 4.3 ir 4.4 skyreliuose.

Uždaviniai

4.1.1. Duoti šie vardinių duomenų tipų aprašai:

type pirštas = (nykštys, smilius, didysis, bevardis, mažylis);
        planeta = (Merkurijus, Venera, Žemė, Marsas, Jupiteris,
                       Saturnas, Uranas, Neptūnas, Plutonas);
        Zodiakas = (Vandenis, Žuvis, Avinas, Tauras, Dvyniai,
                          Vėžys, Liūtas, Mergelė, Svarstyklės,
                          Skorpionas, Šaulys, Ožiaragis);

Nurodykite, kurie reiškiniai netaisyklingi, ir apskaičiuokite taisyklingų reiškinių reikšmes:

a) succ(succ(smilius));
b) pred(pred(Venera));
c) succ(pred(pred(Venera)));
d) Tauras = Avinas;
e) Jupiteris > Tauras;
f) pred(Mergelė);
g) Saturnas > Neptūnas) or (Žuvis > Vėžys);
h) planeta = Žemė.

4.1.2. Duota programa:

program šeima;
  type asmuo = (aš, tu, jis, ji);
          giminė = (tėvas, motina, sūnus, duktė, dėdė, teta);
  var a, b: asmuo;
        x: giminė;
begin
 
{ 1 } a := aš;
  { 2 } b := a;
  { 3 } a := asmuo;
  { 4 } giminė := x;
  { 5 } if ji = asmuo then write('TAIP');
  { 6 } if dėdė <> teta then write('GERAI');
  { 7 } if ji = teta then write('DĖDIENĖ');
  { 8 } if jis = ji then write('NEAIŠKU');
  { 9 } x := tėvas;
  {10} if pred(x) = dėdė then write('XXX')
end;

Kurie sakiniai yra netaisyklingi ir kodėl?

4.1.3. Parašykite sąlyginį sakinį, kuris patikrintų, ar iš keturių atkarpų, kurių ilgiai duoti,
         galima sudaryti kvadratą arba stačiakampį. Rezultato duomenų tipas aprašytas taip:

var forma: (kv, st, ne);
               { kv – kvadratas (tuo pačiu ir stačiakampis) }
               { st – stačiakampis bet ne kvadratas }
               { ne – ne stačiakampis }

4.1.4. Parašykite sąlyginį sakinį, kuris nustatytų, ar dvi duotos savaitės dienos a ir b yra
         gretimos. Pavyzdžiui,

šeštadienis ir sekmadienis yra gretimos,
šeštadienis ir penktadienis yra gretimos,
šeštadienis ir ketvirtadienis nėra gretimos.

4.2. Atkarpos tipai

Dalį iš eilės einančių tipo reikšmių galima pavadinti nauju tipu – atkarpos tipu.

type darbodiena = pirm..penk;
        ma = 6..18                    { moksleivio amžius }

Duomenų tipas, iš kurio imamos reikšmės atkarpos tipui, vadinamas baziniu duomenų tipu. Ką tik aprašyto darbodiena tipo reikšmės yra 4.1 skyrelyje aprašyto savd tipo poaibis. Tipui darbodiena priklauso pirmosios penkios tipo savd reikšmės. Tipas savd yra tipo darbodiena bazinis tipas. Atkarpos tipo apraše nurodomos pirma (ji dar vadinama apatiniu rėžiu) ir paskutinė tipo reikšmė (dar vadinama viršutiniu rėžiu). Tipo darbodiena pirmoji reikšmė yra pirm, paskutinė – penk.

Tipo ma reikšmės yra sveikųjų skaičių poaibis.

Su atkarpos tipo reikšmėmis atliekamos tos pačios operacijos, kaip ir su jo bazinio tipo reikšmėmis, t.y. atkarpos tipas neturi nei savų reikšmių, nei savų operacijų. Tuo jis skiriasi nuo kitų naujų tipų, pavyzdžiui, vardinių.

Taigi atkarpos tipus logiškiau būtų laikyti ne naujais, o išvestiniais tipais, gautais iš bazinio. Naujesnėse programavimo kalbose taip ir daroma. Pavyzdžiui, kalboje Ada atkarpos tipai vadinami bazinių tipų potipiais. Paskalio kalboje potipio sąvokos nėra, todėl atkarpos tipai laikomi lyg ir naujais tipais – jie turi savus vardus, savus kintamuosius. Tačiau atkarpos tipo konstantų ir atkarpos tipo reikšmių nėra. Kai reiškinyje yra atkarpos tipo kintamųjų, tai laikoma, kad tokie kintamieji reiškiniui pateikia bazinio tipo reikšmes. Pavyzdžiui, jeigu yra aprašytas tipas ir kintamieji

type pažymys = 1..5;
var a, b: pažymys;
      i: integer;

tai taisyklingi tokie sakiniai

a: = 1;
b := 5;
i := a + b;
a := (b*i + a) div 3;
b := i div b.

Tačiau neleistini (netaisyklingi) yra sakiniai, kuriuose bandoma atkarpos tipo kintamajam priskirti reikšmę, nepatenkančią į nurodytus rėžius, pavyzdžiui:

a := 6;
b := 0;
a := b*3.

Atkarpos tipai, panašiai kaip ir vardiniai, sudaro tipų šeimą. Programuotojas gali aprašyti kiek nori savų atkarpos tipų.

Atkarpos tipo aprašo dešinėje pusėje gali būti tik konstantos, nors jos būtų pažymėtos ir vardais, pavyzdžiui:

const senas = 1901;
         jaunas = 1987;
type gimimomet = senas..jaunas

Atkarpos tipo reikšmės gali būti tik viename, vientisame intervale. Kitaip aprašyti atkarpos tipo reikšmes (pavyzdžiui, nelygybėmis) nepriimtina, nes tada daug sunkiau būtų kontroliuoti tipus kompiuteryje.

Atkarpos tipai iš esmės naujų galimybių neduoda, tačiau su jais programa dažnai tampa aiškesnė – jau iš tipo aprašo matyti kintamųjų reikšmių rėžiai. Be to, kompiuteris gali patikrinti, ar atliekant programą gautos kintamųjų reikšmės iš tikrųjų yra leistiname intervale. Tais atvejais, kai intervalas nedidelis, reikšmei saugoti gali būti skiriama mažiau atmintinės.

Pakalbėkime, kaip atkarpos tipą galima panaudoti pradiniams duomenims patikrinti.

Daugelio programų rezultatai turi prasmę tik tada, kai pradiniai duomenys yra tam tikrame reikiamo tipo reikšmių intervale. Todėl nepriekaištingai sudarytose programose pirmiausia patikrinama, ar geri pradiniai duomenys, o funkcijų ir procedūrų – ar tinkamos parametrų, kuriais perduodami pradiniai duomenys, reikšmės. Vartojant atkarpos tipus, tokių tikrinimų dažnai galima išvengti. Pavyzdžiui, programoje, nustatančioje, koks bilieto numeris – laimingas ar ne – galime netikrinti, ar pradinis duomuo tikrai yra teigiamas šešiaženklis skaičius, jeigu aprašysime atkarpos tipą

type numeris = 100000..999999

ir pradinį duomenį priskirsime šio tipo kintamajam:

program laimingas;
  type numeris = 100000..999999;
  var x: numeris;
begin
read(x)
...

Tada kompiuteris, atlikdamas sakinį read(x), pats patikrins, ar pradinis duomuo yra nurodytame intervale. Jeigu jis nepateks į atkarpos intervalą, tai kompiuteris praneš apie klaidą. Koks bus pranešimas, kaip kompiuteris reaguos į klaidą (nutrauks skaičiavimą, klaidą taisys ar ignoruos), priklausys nuo konkretaus kompiuterio ir programavimo kalbos. Jeigu norime, kad kompiuteris atliktų reikiamus veiksmus, pavyzdžiui, rašytų pranešimą

PER DIDELIS SKAIČIUS
jeigu x> 999999, arba pranešimą
PER MAŽAS SKAIČIUS

jeigu x< 100000, tai tokiu atveju atkarpos tipas negelbės, nes visus veiksmus reikia užrašyti programoje. Jis taip pat negelbės, jeigu pradinio duomens ribojimo negalima išreikšti intervalu. Pavyzdžiui, atkarpos tipu negalima išreikšti reikalavimo, kad pradinis duomuo būtų lyginis skaičius ir pan.

Matematikoje sveikųjų skaičių aibė begalinė. Programavime duomenų tipas integer yra matematinių skaičių poaibis, ribojamas mažiausio ir didžiausio skaičiaus (maxint). Todėl duomenų tipą integer galima laikyti matematinių sveikųjų skaičių atkarpos tipu.

Uždaviniai

4.2.1. Programoje yra tokie kintamųjų aprašai:

var a:10..30;
      b: 0..20;
      c: 0..10;

Kurie iš išvardytų prieskyros sakinių dėl atkarpos tipų rėžių suderinamumo yra: a) visada teisingi; b) visada neteisingi; c) ne visada teisingi (priklauso nuo reiškinio kintamųjų reikšmių):

    1. b := a;

    2. c := a;

    3. b := c;

    4. b := (c + 30) div 10;

    5. c := a + 1;

    6. a := -b;

4.2.2. Duota programa:

program x;
  var a: -10..10;
        b: 1..5;
        x1, x2, x3, x4, x5, x6, x7: integer;
begin
 
read(a, b);
  x1 := a + b;
  x2 := a - b;
  x3 := -a;
  x4 := -b;
  x5 := a*b;
  x6 := x5 + 1;
  x7 := a*3 + b*2;
  x6 := x1 + x6;
  write(x1, x2, x3, x4, x5, x6, x7)
end.

Kintamuosius x1 – x7 aprašykite tokiais sveikųjų skaičių atkarpos tipais, kad į jos rėžius visada tilptų rezultatas, o reikšmių skaičius būtų mažiausias.

4.3. Variantinis sakinys

Paskalis turi sakinį, specialiai pritaikytą vienam veiksmui iš daugelio veiksmų parinkti. Šis sakinys vadinamas variantiniu. Juo parenkamas vienas iš daugelio sakinių priklausomai nuo reiškinio reikšmės. Sakinio pavidalas yra šitoks:

case reiškinys of
 
c1: S1;
  c2: S2;
  ...
  cn: Sn
end

c1, c2, ..., cn – konstantų sąrašai;
S1, S2, ..., Sn – sakiniai.

Išrenkamas ir vykdomas vienas iš sakinių Si – tas prieš kurį parašytame konstantų sąraše ci yra konstanta, sutampanti su variantinio sakinio antraštėje esančio reiškinio reikšme.

1 pavyzdys. Perskaitomas vienženklis skaičius, o spausdinamas šis skaičius žodžiu.

program skaitmuo;
  var s: integer;
begin
 
read(s);
  case s of
   
0: write('nulis');              5: write('penki');
    1: write('vienas');            6: write('šeši');
    2: write('du');                 7: write('septyni');
    3: write('trys');               8: write('aštuoni');
    4: write('keturi');             9: write('devyni')
  end;
writeln
end.

Reiškinys ir konstantos turi būti to paties diskrečiojo duomenų tipo. Mums jau žinomi sveikieji skaičiai ir loginės reikšmės priklauso diskretiesiems duomenų tipams, todėl jie gali būti panaudoti variantiniame sakinyje. Tuo tarpu realieji skaičiai šiam tikslui netinka.

Turbo Paskalyje vietoj iš eilės einančių konstantų sąrašo galima rašyti konstantų atkarpą: pirmąją ir paskutinę konstantų reikšmes, atskirtas dviem taškais. Pavyzdžiui, vietoj

2, 3, 4, 5
galima rašyti
2..5

Be to, paskutinėje šakoje vietoj konstantų sąrašo ir po jo einančio dvitaškio gali būti žodis else. Sakinys, parašytas po else, atliekamas tuo atveju, kai reiškinio reikšmė nesutampa su jokia konstanta ir nepatenka į jokį konstantų intervalą.

2 pavyzdys. Tarkime, kad kintamasis aa yra sveikojo tipo.

case aa of
 
0, 2, 4, 6, 8: write('lyginis vienženklis');
  1, 3, 5, 7, 9: write('nelyginis vienženklis');
  10..99 :        write('dviženklis');
  else :           write('neigiamas arba didesnis už 99')
end

Kiekvienoje varianto šakoje gali būti rašomas tik vienas sakinys. Tačiau jis gali būti bet koks: prieskyros, sąlyginis, variantinis, sudėtinis ir kt. Kai reikia atlikti kelis sakinius, tai jie apjungiami į vieną sudėtinį.

Šakojimąsi į daugelį krypčių galima išreikšti ir vienu variantiniu sakiniu ir daugeliu vienas į kitą įdėtų sąlyginių sakinių. Vieno variantinio sakinio atvejis paprastesnis, tačiau juo galima išreikšti tik tokį šakojimąsi, kurį valdo vieno reiškinio reikšmė. Kai šakojimąsi priklauso nuo kitokių (sudėtingesnių) sąlygų, tenka naudoti sąlyginius sakinius.

Uždaviniai

4.3.1. Pradinis duomuo – mėnesio numeris. Parašykite programą, kuri spausdintų mėnesio
         pavadinimą:

4.3.2. Kintamasis b yra loginio tipo. Variantinį sakinį

case log of
 
false: a := a+1;
  true : b := b+1
end

pakeiskite jam ekvivalenčiu, t.y. atliekančiu tokius pačius veiksmus, sąlyginiu sakiniu.

4.3.3. Pradiniai duomenys – du sveikieji skaičiai: metai ir mėnuo. Parašykite programą, kuri
         rastų, kiek dienų turi mėnuo.

Apie keliamųjų metų nustatymą žr. 3.1.12 uždavinį.

Praktikos darbas

4.3.1. Pinigų suma žodžiu. Sudarykite programą, kuri duotą pinigų sumą (0..9999) litais parašytų žodžiu, o pabaigoje. Pavyzdžiui, jeigu pradinis duomuo 127, programa turi parašyti:

vienas šimtas dvidešimt septyni litai

jeigu pradinis duomuo 5819, programa turi rašyti

penki tūkstančiai aštuoni šimtai devyniolika litų

4.4. Žinomo kartojimų skaičiaus ciklas

Kai kartojimų skaičius žinomas prieš atliekant ciklą, patogu vartoti šitokio pavidalo ciklą:

for ciklo kintamasis := reiškinys1 to reiškinys2 do
  sakinys

Ciklo antraštė prasideda žodžiu for. Po jo rašomas ciklo kintamojo vardas. Toliau nurodoma, su kokiomis ciklo kintamojo reikšmėmis turi būti atliekamas ciklas.

Sakinys atliekamas su skirtingomis ciklo kintamojo reikšmėmis. Pirmoji jo reikšmė yra reiškinys1. Antroji – reikšmė, einanti po reiškinio reiškinys1 reikšmės, t.y., succ(reiškinys1), trečioji – succ(succ(reiškinys1) ir t.t. Paskutinį kartą sakinys atliekamas kai ciklo kintamojo reikšmė yra reiškinys2.

1 pavyzdys. Sakinių seka skaičiui a pakelti laipsniu n (n => 0).

p := 1;
for i := 1 to n do
  p := p*a

Ciklas atliekamas n kartų, t.y. tiek kartų, kokiu laipsniu keliamas skaičius a. Kiekvieną kartą atliekant ciklą, rezultatui p priskiriama vis nauja reikšmė, kuri lygi ankstesnei jo reikšmei, padaugintai iš kintamojo a reikšmės. Pavyzdžiui, kai a = 3 ir n = 2, ciklas atliekamas du kartus ir gaunama p = 9, t.y. rezultatas lygus skaičiaus 3 kvadratui. Kai a = 5 ir n = 3, ciklas atliekamas tris kartus ir gaunama p = 125 (skaičiaus 5 kubas).

Kai n = 0, ciklas neatliekamas nė karto. Tada rezultatas p = 0, kas atitinka kėlimo laipsniu operacijos apibrėžtį.

2 pavyzdys. Programa, pagal kurią randama nurodyto intervalo visų skaičių kvadratų suma, lyginių skaičių kvadratų suma ir nelyginių skaičių kvadratų suma atskirai.

program sumos;
  var m, n,           { intervalas }
        slyg,            { lyginių suma }
        snelyg,        { nelyginių suma }
        k: integer;
begin
 
read(m, n);
  slyg := 0; snelyg := 0;
  for k := m to n do
    if
k mod 2 = 0
      then slyg := slyg + k*k
      else snelyg := snelyg + k*k;
  writeln(slyg + snelyg, slyg: 10, snelyg: 10)
end.

Šiame pavyzdyje ciklui priklauso tik vienas sakinys, parašytas po jo antraštės. Tai sąlyginis sakinys. Vadinasi, sąlyginio sakinio veiksmai bus kartojami tiek kartų, kiek kartų bus atliekamas ciklas. Rašymo sakinys ciklui nepriklauso. Todėl atliekamas tik vieną kartą – pasibaigus ciklui. Kai m = 2 ir n = 4, ciklas atliekamas tris kartus ir ekrane matysime šitokius rezultatus:

29   20   9

Kai reikia kartoti kelių sakinių veiksmus, tie sakiniai sujungiami į vieną sudėtinį sakinį. Į ciklą gali įeiti kitas ciklas, o tame, mažesniame, cikle gali būti naujų ciklų ir t.t.

3 pavyzdys. Programa skaičių nuo 1 iki n m-tiesiems laipsniams sumuoti:

program LaipsniųSuma;
  var n,                       { intervalo pabaiga }
        r,                        { laipsnio rodiklis }
        p,                       { vieno skaičiaus laipsnis }
        s,                       { laipsnių suma }
        i, j: integer;
begin
 
read(n, r);
  s := 0;
  for i := 1 to n do
    begin
     
p := 1;
      for j := 1 to r do
       
p := p*i;
        s := s+p
      end;
  writeln(s)
end.

Išorinis ciklas (jo antraštė for i := 1 to n do) atliekamas n kartų – su kiekvienu skaičiumi vieną kartą. Šio ciklo kartojamas sakinys yra sudėtinis. Jame yra kitas ciklas i-tojo skaičiaus r-tajam laipsniui rasti. Šis ciklas su kiekvienu skaičiumi atliekamas tiek kartų, kokiu laipsniu reikia jį kelti. Pavyzdžiui, kai r = 3, ciklas su kiekvienu skaičiumi atliekamas tris kartus (j = 1, 2, 3). Jeigu n = 20, tai išorinis ciklas atliekamas 20 kartų, o vidinis 20 . 3 = 60 kartų.

Abiejų reiškinių (reiškinys1 ir reiškinys2) reikšmės yra apskaičiuojamos tik vieną kartą – prieš atliekant ciklą, įsimenamos ir toliau naudojamos. Todėl komponentų keitimai ciklo sakinyje nebeturi įtakos ciklo kartojimų skaičiui.

Jeigu reiškinys1 = reiškinys2, tai ciklas atliekamas vieną kartą.
Jeigu reiškinys1 > reiškinys2, tai ciklas neatliekamas nė karto.

Jei ciklo veiksmus reikia atlikti perbėgant ciklo kintamojo reikšmes atvirkščia tvarka – nuo didžiausios iki mažiausios, tai tada ciklo antraštėje vietoj žodžio to rašomas žodis downto.

for ciklo kintamasis := reiškinys1 downto reiškinys2 do

Šis ciklas atliekamas atvirkščiai, negu anksčiau nagrinėtas. Pirmoji ciklo kintamojo reikšmė yra reiškinys1, antroji – pred(reiškinys1) trečioji – pred(pred(reiškinys1)) ir t.t. Paskutinį kartą sakinys atliekamas kai ciklo kintamojo reikšmė yra reiškinys2.

5 pavyzdys. Programa, rašanti visus vienženklius skaičius atvirkščiai (mažėjančiai).

program atv;
  var sk: integer;
begin
  for
sk := 9 downto 0 do
   
write(sk: 2);
  writeln
end.

Ciklas su žodžiu downto atliekamas vieną kartą, jeigu reiškinys1 = reiškinys2, t.y., taip pat, kaip ir ankstesnis ciklas. Tačiau jis neatliekamas nė karto esant priešingai sąlygai, t.y., jeigu reiškinys1 < reiškinys2.

Ciklo for kintamasis ir abu jo reiškiniai turi būti tuo paties duomenų tipo. Dažniausiai jie būna sveikojo tipo. Tačiau gali būti ir bet kurio kito paprastojo diskrečiojo duomenų tipo, pavyzdžiui, vardinio, loginio, simbolinio (žr. 4.1 skyr.). Dėl to apibrėždami ciklo veikimą vengėme sakyti, kad kai ciklas kartojamas, tai jo kintamojo reikšmė padidinama arba sumažinama vienetu, o sakėme, kad imama tolesnė arba prieš ją einanti reikšmė. Mat sudėties ir atimties operacijas turi tik skaičiai. Kiti diskretieji duomenų tipai (pvz., vardinis) aritmetinių operacijų neturi. Tačiau visi diskretieji duomenų tipai turi tolesnės arba prieš einančios reikšmės gavimo operacijas (succ ir pred).

Realieji skaičiai nepriklauso diskrečiųjų duomenų tipų grupei, todėl nei ciklo kintamojo, nei kurio nors reiškinio tipas negali būti realusis.

Ciklo kintamasis duoda nemažai naudos, bet su juo atsiranda ir problemų. Kokia bus ciklo kintamojo reikšmė, atlikus ciklą? Į šį klausimą ne taip lengva atsakyti. Logiškai galvojant, kintamojo reikšmė turėtų būti lygi reiškinio, esančio po žodžio to, reikšmei. Tačiau kompiuteris dažniausiai ciklo kintamojo reikšmę pirmiau padidina (sumažina) ir tik po to tikrina, ar ji dar patenka į leistinus rėžius. Tokiu atveju ciklo kintamojo reikšmė būtų lygi succ(reiškinys2) arba pred(reiškinys1) – downto atveju. Be to, tokiu atveju nebūtų galima parašyti ciklo, perrenkančio visas kurio nors diskrečiojo duomenų tipo reikšmes. Dėl to, susitarta ciklo kintamojo reikšmės nenaudoti už ciklo ribų. (Laikoma, kad užbaigto ciklo kintamojo reikšmė tampa neapibrėžta.).

Ciklas for yra skirtas iš anksto žinomam veiksmų kartojimų skaičiui užrašyti, todėl nedera jo paskirties iškreipti keičiant ciklo viduje jo kintamojo reikšmę.

Visus Paskalio kalbos ciklus skirstėme į dvi rūšis: žinomo kartojimo skaičiaus (for) ir nežinomo kartojimų skaičiaus (while, ir repeat).

Kada katrą ciklą naudoti? Jeigu dar prieš atliekant ciklą žinoma, kiek kartų reikės jį kartoti, tai labiau tinka ciklas, kurio antraštė prasideda žodžiu for. Tada programa būna trumpesnė ir vaizdesnė. Jeigu kartojimų skaičiaus prieš atliekant ciklą negalima nustatyti, reikia naudoti ciklą su žodžiu while arba repeat.

Uždaviniai

4.4.1. Kiek kartų bus atliekamas ciklas, kurio antraštė yra šitokia:

a) for k := 10 to 20 do
b) for k := 20 to 10 do
c) for k := -1 to 1 do
d) for k := a to a do
e) for k := a to a+10 do
f) for k := -a to a do
g) for k := 10 downto 20 do
h) for k := 20 downto 10 do

4.4.2. Kokius skaičius matysime ekrane atlikę šią programą.

program bandymas;
  var a, b, i: integer;
begin
 
a := 0;
  b := 5;
  for i := a to b do
    begin
     
write(i: 2);
      b := b-1
    end;
  writeln
end.

4.4.3. Sudarykite programą visų teigiamų nelyginių dviženklių skaičių kvadratų sumai rasti.

4.4.4. Pradiniai duomenys – geometrinės progresijos pirmasis narys ir jos vardiklis.
         Sudarykite programą, kuri apskaičiuotų ir išspausdintų 10 pirmųjų progresijos narių.

4.4.5. Pradiniai duomenys – aritmetinės progresijos pirmasis narys, jos skirtumas ir
         natūralusis skaičius n. Sudarykite programą, kuri apskaičiuotų ir išspausdintų 10 iš
         eilės einančių progresijos narių, pradedant n-tuoju.

4.4.6. Turime vieną ciklą įdėtą į kitą ciklą:

for i := 1 to n do
  for j := 1 to m do

Raskite (jei galima) tokias n ir m reikšmes (konstantas), kad ciklai būtų atliekami šitiek kartų:

a) išorinis ciklas būtų atliekamas 5 kartus, vidinis – 10 kartų;
b) išorinis ciklas būtų atliekamas 10 kartų, vidinis – 10 kartų;
c) išorinis ciklas būtų atliekamas 10 kartų, vidinis – 0 kartų;
d) vidinis ciklas būtų atliekamas 12 kartų;
e) vidinis ciklas būtų atliekamas 13 kartų;
f) išorinis ciklas būtų atliekamas 0 kartų, vidinis – 10 kartų.

4.4.7. Kiek kartų bus atliekamas ciklas

n := 10
  for k := 1 to n do
   
n := n-1

4.4.8. Ar ciklas for gali būti nebaigtinis?

4.4.9. Kokie nekorektiškumai yra šioje programoje?

program GalimosKlaidos;
  var k: integer;
begin
  for
k := 1 to 10 do
    begin
     
k := k+1;
      writeln(k: 5);
    end;
  writeln(k)
end
.

4.4.10. Turime dvi programas, skirtas tam pačiam darbui: dešimčiai skaitmenų rašyti. Kuri
           iš jų neteisinga ir kodėl?

program pirma;
  var k: 0..9;
begin
  while
k <= 9 do
    begin
     
write(k: 2);
      k := k + 1
    end
end
.

program antra;
  var k: 0..9;
begin
  for
k := 0 to 9 do
   
write(k: 2)
end.

4.4.11. Programuotojas, išbandęs 4.4.9 uždavinio programą Turbo Paskaliu, nepastebėjo
           jokių klaidų. Tuo tarpu uždavinio sprendime pateikti net du nekorektiškumai. Kodėl
           teorija nesiderina su praktika

Praktikos darbas

4.4.1. Daugianario reikšmės skaičiavimas. Parašysime programą, kuri apskaičiuotų daugianario

anxn + an-1xn-1 + an-2xn-2 + ... + a1x + a0

reikšmę.

Analogišką programą trečiojo laipsnio daugianariui jau rašėme (žr. 3.4 skyr., 2 pavyzdį). Turėdami ciklą galime lengvai parašyti programą bet kurio laipsnio daugianariui skaičiuoti.

Daugianarį pertvarkysime – užrašysime jį Hornerio schema

(... (((an)x + an-1)x + an-2)x + ... + a1)x + a0

Šitaip užrašyto daugianario reikšmei skaičiuoti reikės mažiau daugybos operacijų. Be to, pradėjus jį skaičiuoti nuo koeficiento su didžiausiu indeksu, galima nežinoti, kiek dar bus koeficientų, t. y. koks daugianario laipsnis.

Rašome programą.

program daugianaris;
  var x,
        a,                         { kuris nors koeficientas }
        px: real;                { daugianario reikšmė }
        koef: text;             { daugianario koeficientai }
begin
 
assign(koef, 'KOEF.TXT'); reset(koef);
  px := 0;
  write('x = ');
  read(x);
  write(' Surinkite daugianario koeficientus ');
  writeln('a(n), a(n-1), ... a(1), a(0)');
  writeln (' Nepraleiskite nulių! ');
  while not eof(koef) do
    begin
     
px := px*x;
      read(koef, a);
      px := px+a
    end;
 
writeln;
  writeln('x = ', x: 10, px: 15)
end.

Kintamasis a atstovauja visiems daugianario koeficientams. Kai perskaitoma kurio nors koeficiento reikšmė, ji pridedama prie jau turimos daugianario reikšmės ir pasidaro nebereikalinga. Todėl tą patį kintamąjį galima panaudoti naujai perskaitytai daugianario reikšmei įsiminti.

Naudodamiesi kompiuteriu ir šia programa, apskaičiuokite šitokių daugianarių reikšmes:

a) 5x3 + 2x2 + 3x + 2, kai x = 1, 100;
b) 2x8 + x6 + 4x4 - 5x2 + x, kai x = 0, 1, 2, 3.

 

4.5. Skaičių perrinkimo uždaviniai

Kompiuteris veikia greitai. Todėl uždavinius galima spręsti bandymų keliu. Paeiliui išbandomi visi variantai ir atrenkami tie, kurie tenkina uždavinio sąlygas.

Matematikoje yra suformuluota nemažai uždavinių, kuriuose reikia rasti skaičius, tenkinančias tam tikras savybes. Kol nebuvo kompiuterių, tokių skaičių paieška buvo savotiškas sportas. Dabar kompiuteriu galima greitai patikrinti daugybę skaičių ir sportu tampa programų tokiems uždaviniams rašymas.

Skaičių, tenkinančių tam tikras savybes, paieškos algoritmus galima suskirstyti į tris grupes:

1. Pilnas perrinkimas. Tikrinami visi skaičiai iš eilės. Aišku, kad šitaip galima patikrinti tik baigtinio intervalo skaičius.

2. Ribotas perrinkimas. Įrodoma, kad ieškomą savybę gali turėti tik skaičiai, patenkantys į tam tikrus intervalus. Tada pakanka patikrinti tik tuos intervalus.

3. Skaičių generavimas. Randamas būdas, kaip gauti visus skaičius, tenkinančius reikiamą sąlygą, be perrinkimo. Tada rašoma programa, generuojanti ieškomą skaičių aibę.

Pilnas perrinkimas. Tai paprasčiausi algoritmai, kai tikrinami visi skaičius iš eilės.

1 pavyzdys. Reikia rasti visus intervalo [m; n] skaičius, kurių skaitmenų sumos kubas lygus pačiam skaičiui.

program kubai;
  var m, n,            { intervalo rėžiai }
        k,                 { kandidatas į ieškomus skaičius }
        s,                 { skaičiaus k skaitmenų suma }
        kk: integer;
  begin
 
read(m, n);
  for k := m to n do
     begin
       
s := 0;
        kk := k;
        while kk > 0 do
           begin
              
s := s + kk mod 10;
               kk := kk div 10
           end;
        if k = s*s*s then writeln(k)
     end
end
.

2 pavyzdys. Visų skaičiaus daliklių radimas.

program dalikliai;
  var n, { duotas skaičius }
        dal: integer; { kandidatas į duoto skaičiaus daliklius }
begin
 
read(n);
  for dal := 1 to n do
     if
n mod dal = 0 then writeln(dal)
end.

Šioje programoje jau galima įžiūrėti tam tikrą perrinkimo ribojimą – tikrinami tik skaičiai, nedidesni už duotą skaičių. Mat laikome, kad savaime aišku, jog skaičiaus daliklis negali būti didesnis už jį patį.

Ribotas perrinkimas.

3 pavyzdys. Skaičius n neturi daliklių iš intervalo [n div 2 + 1; n - 1]. Atmetę šį intervalą beveik dvigubai sumažinsime ciklo kartojimų skaičių.

program dalikliai2;
   var n,                            { duotas skaičius }
         dal: integer;              { kandidatas į duoto skaičiaus daliklius }
begin
 
read(n);
  for dal := 1 to n div 2 do
     if
n mod dal = 0 then writeln(dal);
  writeln(n)                         { n yra skaičiaus n daliklis }
end.

Paieškos intervalą galima dar daugiau apriboti (žr. 4.5.1 užd.).

Paminėsime keletą įdomiomis savybėmis pasižyminčių skaičių.

Draugiškaisiais skaičiais vadinami du natūralieji skaičiai, kurių kiekvienas lygus antrojo skaičiaus visų daliklių, išskyrus jį patį, sumai.

Tobuluoju skaičiumi vadinamas natūralusis skaičius, lygus visų savo daliklių, išskyrus jį patį, sumai.

Automorfiniu skaičiumi vadinamas skaičius, lygus savo kvadrato paskutiniams skaitmenims.

Šių ir daugelio kitų įdomių skaičių paieškos algoritmai yra aprašyti knygoje [3].

4 pavyzdys. Tarkime, kad reikia parašysime programą, kuri rastų visus skaičius, kurie lygūs savo skaitmenų kubų sumai. Iš pradžių tai atrodo neįveikiamas uždavinys, kadangi neįmanoma patikrinti visos begalinės skaičių aibės. Tačiau galima įrodyti, kad šią savybę gali turėti tik skaičiai, patenkantys į baigtinį intervalą, nedidesni kaip keturženkliai. Įrodymui reikalingus duomenis apie įvairiaženklius skaičius surašysime į lentelę.

Keliaženkliai skaičiai

Mažiausias skaičius

Didžiausia skaitmenų kubų suma

Vienaženkliai

1

729

Dviženkliai

10

1458

Triženkliai

100

2187

Keturženkliai

1000

2916

Penkiaženkliai

10000

3645

Skaitmenų kubų sumos auga lėčiau, negu skaičiai. Didžiausia penkiaženklio skaičiaus skaitmenų suma yra mažesnė už patį mažiausią penkiaženklį skaičių. Vadinasi penkiaženkliai skaičiai ieškomos savybės nebegali turėti. Juo labiau šešiaženkliai, septynženkliai ir t.t. Todėl pakanka apriboti paiešką iki keturženklių skaičių. Bet ir keturženklius skaičius galima tikrinti ne visus, o tik iki 2916, nes didesnės keturženlių skaitmenų kubų sumos už šį skaičių nebėra. geriau pagalvojus.

program kubai2;
  var m, n,                  { intervalo rėžiai }
        k,                       { kandidatas į ieškomus skaičius }
        s,                       { skaičiaus k skaitmenų suma }
        sss,                    { skaičiaus k skaitmenų kubų suma }
        kk: integer;
begin
  for
k := 1 to 2916 do
     begin
        
sss := 0;
         kk := k;
         while kk > 0 do
             begin
                 s := kk mod 10;
                 sss := sss + s*s*s;
                 kk := kk div 10
             end;
         if k = sss then writeln(k)
     end
end
.

Skaičių, kurie lygūs savo skaitmenų sumos kubui, intervalas taip pat ribotas. Toks uždavinys buvo pateiktas pirmojo Lietuvos jaunųjų programuotojų konkurso dalyviams ir yra aprašytas knygoje [4].

Skaičių generavimas.

5 pavyzdys. Tarkime, kad reikia rasti visus duoto intervalo skaičius, kurie dalosi iš 7. Paprasčiausias sprendimas – patikrinti visus intervalo skaičius. Tačiau galima perrinkimo išvengti: rasti pirmąjį (mažiausią) skaičių, o kitus gauti prie jo pridedant po 7.

program septynetas;
  var m, n,                   { intervalo rėžiai }
        k: integer;            { ieškomas skaičius }
begin
 
read(m, n);
  k := m;
  while k mod 7 <> 0 do
    
k := k + 1;
  while k <= n do
     begin
         writeln(k);
         k := k + 7
     end
end
.

Uždaviniai

4.5.1. Suradus vieną skaičiaus daliklį ir iš jo padalijus skaičių galima gauti kitą daliklį –
         rasto daliklio „porininką“. Pavyzdžiui, suradę skaičiaus 28 daliklį 2 galima gauti kitą
         skaičiaus daliklį 28 div 2 = 14. Tuo pasinaudodami patobulinkite 3 pavyzdžio
         programą sumažindami perrinkimų skaičių.

4.5.2. Parašykite programą skaičiaus skaidymui į pirminius daugiklius.

4.5.3. Parašykite programą, kuri rašytų pirmąjį dešimtuką skaičių, dalių iš 2, 3 ir 5.

4.6. Diskretieji ir tolydieji duomenys

Kompiuterio prigimtis yra diskreti, dar kitaip vadinama skaitmeninė. Visi duomenys jame saugomi diskrečiu pavidalu: nulių ir vienetų kodais. Tačiau matematikoje ir realiame gyvenime yra dar kita duomenų rūšis – tolydieji duomenys. Tai realieji skaičiai. Realiųjų skaičių aibė yra begalinė. Skaičių begalybė pasireiškia ne tik skaičiams be galo didėjant arba be galo mažėjant, bet ir į gylį. Tarp bet kurių dviejų realiųjų skaičių galima rasti be galo daug kitų realiųjų skaičių. Pavyzdžiui, tarp skaičių

1,123456788 ir
1,123456789 yra skaičiai:

1,1234567881
1,12345678812
1,12345678820001 ir t.t.

Kompiuteris ne tik diskretus, bet ir baigtinis: skaičiui saugoti skiriamas baigtinis atmintinės kiekis. Taigi kompiuteryje realieji skaičiai vaizduojami apytiksliai, baigtinėmis sveikųjų skaičių sekomis. Dėl to atsiranda paklaidos.

Daugumos praktinių uždavinių skaičiavimo paklaida būna maža. Tačiau kartais pravartu rezultatus apskaičiuoti su kuo mažesne paklaida. Ypač tai svarbu, kai paklaida kaupiasi, atliekant skaičiavimus cikluose. Žinant, kaip realieji skaičiai vaizduojami kompiuteryje, galima suvokti, kokias paklaidas jis daro. Apie tai ir kalbėsime.

Beveik visuose kompiuteriuose realieji skaičiai vaizduojami vadinamuoju slankaus kablelio pavidalu. Paaiškinsime jį. Vienam realiajam skaičiui skirtas atmintinės laukas padalijamas į dvi dalis. Vienoje jų saugomas pats skaičius, kitoje – daugiklio laipsnis. Sakykime, kad turime kompiuterį, kuriame skaičiui skiriamos 6 skiltys o daugiklio laipsniui – 2 skiltys. Tada laukas būtų padalytas taip:

±

X

X

X

X

X

X

±

X

X

         skaičius                                                       daugiklio 
                                                                            laipsnis

Čia ženklais X pažymėti skaitmenys.

Pavyzdžiui, skaičius 0.25E-8 tokiame kompiuteryje būtų užrašytas šitaip:

+

2

5

X

X

X

X

±

X

X

 

Raidė E į atmintį neįrašoma – ir taip aišku skaičiaus ir jo daugiklio laipsnio riba. Nerašomas ir trupmeninę dalį nuo sveikosios atskiriantis taškas (kablelis). Susitariama, kad jis bus visada toje pačioje vietoje, pavyzdžiui, prieš pirmąją skaičiaus skiltį, t. y. visi skaičiai neturės sveikosios dalies. Na, o tų skaičių, kurie iš tikrųjų turi sveikąją dalį, taškas perkeliamas į kairę, atitinkamai padidinus daugiklio laipsnį. Pavyzdžiui, skaičius

67.5R-5

būtų užrašomas taip

0.675E-3

Siekiant kuo didesnio skaičių tikslumo, jie „sukoreguojami" taip, kad pirmoji trupmeninė skiltis būtų reikšminga t. y. nebūtų lygi nuliui. Pavyzdžiui, skaičius

0.00125E-5

užrašomas taip

0.125E-7

Pateikiame daugiau pavyzdžių.

 Skaičius programoje                            Skaičius kompiuteryje

125E50

+

1

2

5

0

0

0

+

5

3

0.0000000137

+

3

7

0

0

0

0

-

0

7

3.14

+

3

1

4

0

0

0

+

0

1

-3E8

-

3

0

0

0

0

0

+

0

9

12345.12345

+

1

2

3

4

5

1

+

0

5

9999999999E89

9

9

9

9

9

9

9

+

9

9

Pats didžiausias skaičius, kurį galima įrašyti į čia pavaizduoto kompiuterio atmintį, būtų 0.999999E99, t. y. 1099 – 1093. Pats mažiausias (pagal modulį) šešių skilčių tikslumo skaičius būtų 0.100000E-99, t. y. 10–100. Taigi leistinas skaičių intervalas labai platus. Neįmanoma net įsivaizduoti tokių didelių arba tokių mažų skaičių. Aptariamo kompiuterio atmintyje saugomos tik šešios reikšminės skaičiaus skiltys, nepaisant, kokie jie – dideli ar maži. Todėl visame leistiname skaičių intervale santykinė paklaida yra ta pati, o absoliučioji keičiasi – didėja, didėjant skaičiams. Pavyzdžiui, skaičius

100000000.0

nagrinėjamame kompiuteryje būtų užrašytas taip:

0.100000E09

Jam artimiausias didesnis skaičius, kurį galima įrašyti į kompiuterio atmintinę būtų

0.100001E09
t. y.
100001000.0

Taigi du gretimi skaičiai skiriasi 1000, t. y. kompiuteris skaičiuoja tūkstančių tikslumu. Todėl galime būti beveik tikri: kai a = 1E8, skaičiuojant nagrinėjamu kompiuteriu, lygybė

a = a+1

bus tenkinama!

Kai skaičiai labai dideli, pavyzdžiui, a = 1E50, lygybė

a = a+1

gali būti tenkinama skaičiuojant kiekvienu kompiuteriu!

Taigi realiaisiais skaičiais galima apytiksliai pavaizduoti ir labai didelius sveikuosius skaičius. Todėl posakis, kad realiaisiais skaičiais programavime vadinami trupmeniniai skaičiai, nėra tikslus. Geriau būtų sakyti, kad realiaisiais skaičiais vadinami apytiksliai skaičiai.

Daugiau medžiagos apie realiuosius skaičius galima rasti straipsnyje [5].

Realieji skaičiai kompiuteriuose vaizduojami nevienodai – gali būti kitoks skilčių skaičius skaičiui arba laipsnio rodikliui saugoti, skaičiai koduojami dvejetaine sistema. Tačiau bendri vaizdavimo principai yra tie patys.

Uždaviniai

4.6.1. Ką parašys kompiuteris, atlikęs šitokią programą

program paklaida;
  const da = 654321E5;
           db = 654320E5;          { dideli skaičiai }
           mc = 654321;             { mažas skaičius }
  var a, b: real;
begin
 
a := da+mc-db;
  b := da-db+mc;
  writeln(a);
  writeln(b)
end.

4.6.2. Kurios iš šių reiškinių reikšmės yra nepriimtinos, t.y., rodančios, kad jas pateikęs
         kompiuteris dirba blogai (yra sugedęs)?

a) a/5.0*5.0 = a*5.0/5.0           false
b) a/5.0*5.0 = a*5.0/5.0           true
c) 5/2.0 = 2.5                         true
d) 5/2.0 = 10.0                       true
e) 25000 = 25E3                    false
f) 25000 <> 25E3                   true
g) 2500 = 30E3                      true
h) 12E50 = 12E50+1.0           true
i) 12E50 = 12E50+1.0            false

E Ankstesnis puslapis

3 Turinys

Kitas puslapis F

tus0.gif (69 bytes)