ELEKTRONINĖS KNYGOS |
|
|
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ų):
-
b := a;
-
c := a;
-
b := c;
-
b := (c + 30) div 10;
-
c := a + 1;
-
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:
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:
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. 10100.
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 |
|
|
|
|