V. Aritmetika

A REXX-ben (más programozási nyelvekhez hasonlóan) kitüntetett karakterek szolgálnak az aritmetikai (matematikai) operátorok megadására. Az alap operátorkészlet definiálásához használt karakterekkel már találkoztunk: +, -, *, / és %. Egyes operátorok egynél több karakterbôl is állhatnak. Ilyenkor az operátort megadó karakterek szóközt, vagy akár megjegyzést is tartalmazhatnak:

3**2
3 ** 2
3 * * 2
3 * /* megjegyzés */ * 2
3 /* megjegyzés */ ** 2

A fenti példában szereplô kifejezések mindegyike ugyanazt a mûveletet, a három négyzetre emelését írja le. Bár szintaktikailag a példák mindegyike tökéletes, az utolsó kettô használatát lehetôleg kerüljük.

A megadandó operandusok száma alapján az operátorok lehetnek unárisak, vagy binárisak. Az unáris operátorok csak egy operandust igényelnek, s mivel ezek az operátorok megelôzik az operandust, ezért elôtag operátoroknak is nevezik ôket.

A matematikai operátorokat természetesen csak REXX számokkal használhatjuk. Ha az operandus nem szám, akkor a REXX egy hibaüzenetet fog visszaadni.

/* Példaprogram aritmetikai hibára  */

a = 10
c = a + b
b = 6
EXIT

A program futtatásakor pedig a következô hibát kapjuk:

     4 +++   c = a + b;
REX0041: Error 41 running E:\OS2TIMES\lecke5a.cmd, line 4: Bad arithmetic conversion

A hibaüzenet jogos, mivel a b szimbólum az összeadás pillanatában még nem szám, hiszen csak a következô sorban kap értéket.

Az összeadás

A összeadás a + operátor segítségével történik. Ez egy bináris operátor, mivel két szám szükséges a mûvelethez. A számok (vagy változók), amelyeket összeadunk, az összeadás után is megtartják eredeti értéküket, s a mûvelet eredménye egy harmadik változóban kerül eltárolásra, vagy egy újabb mûveletben vesz részt. Gyakran használt elem a programokban a számláló, amely az összeadás mûveletén alapszik:

szamlal = szamlal + 1

A példában szereplô számláló értéke eggyel növekszik az összeadás végrehajtása után, s az eredmény is a számlálóban kerül eltárolásra. Ez azt jelenti, hogy a számláló aktuális értékébôl mindig tudjuk, hogy a mûvelet hányszor került végrehajtásra. Természetesen kettônél több számot is összeadhatunk egy lépésben:

negyedev = januar + februar + marcius

A kiértékelés balról jobbra történik, azaz elôször a januar és a februar adódik össze. Ennek az összeadásnak az eredménye adódik aztán a marciushoz, s a végeredmény a negyedev változóban kerül eltárolásra.

A kivonás

A kivonás a - operátor segítségével történik. Ez szintén bináris operátor, mivel most is két szám szükséges a mûvelethez. A kivonás során az operátor jobb oldalán álló szám vonódik ki a bal oldali számból. A mûveletben résztvevô számok értéke itt sem változik, mivel az eredmény egy harmadik változóban tárolódik el, vagy egy újabb mûveletben vesz részt. Egy lépésben több kivonás is elvégezhetô, azonban a mûveletben résztvevô számok sorrendjétôl függôen az eredmény nagyban függhet. Lássunk erre egy példát:

fizetes1 = brutto - adotetel1 - adotetel2
fizetes2 = brutto - adotetel2 - adotetel1
fizetes3 = adotetel1 - adotetel2 - brutto

Mivel a kiértékelés balról jobbra történik, nyilvánvaló, hogy a fenti példák alapján kiszámolt fizetes1 és fizetes2 megegyezik, azonban a fizetes3 már teljesen más eredményt ad!

A negálás

A negálás megváltoztatja a mûveletben résztvevô szám elôjelét, már amennyiben a szám nem nulla. A negálás az unáris - operátor segítségével történik. A REXX-ben létezik az unáris + operátor is. Ez az operátor nullát ad az operandushoz, azaz gyakorlatilag nem csinál semmit, s mi is csak a teljesség kedvéért említjük meg.

A szorzás

A szorzás operátora a *. Ez is egy bináris operátor, mivel a * jel bal és jobb oldalán álló számokat szorozza össze. Egy lépésben több számot is összeszorozhatunk. A kiértékelés szorzás estében is balról jobbra történik. A végeredmény független a mûveletben résztvevô számok sorrendjétôl.

Az osztás

Az osztáshoz három operátor is a rendelkezésünkre áll. A leggyakrabban a közönséges értelemben vett osztást végzô / operátort használjuk. Ezen kívül létezik még a % operátor, amely az osztás után kapott szám egész részét adja vissza. A harmadik a // operátor, amely az osztás után kapott maradékot képzi:

25/2  -> 12.5
25%2  -> 12
25//2 ->  1

Hatványozás

Az utolsó, eddig még nem tárgyalt alapoperátor a hatványozás, melynek jele a **. Ez tulajdonképpen a szorzás praktikus rövidítése, hiszen pl. a 4 ** 5 helyettesíthetô a 4*4*4*4*4-gyel. Az eddig tanult mûveletek gyakorlására nézzünk meg egy példaprogramot, amely a bevitt számok átlagát képzi.

/* Példaprogram a számok átlagának kiszámítására */

total = 0
szamlalo = 0

ujadat:
SAY "Gépelj be egy számot, vagy nyomd meg az ENTERT-t!"
PULL szam
IF szam = "" THEN
	SIGNAL vegeredmeny
IF Datatype(szam) <> 'NUM' THEN 
	SIGNAL hiba
total = total + szam
szamlalo = szamlalo + 1
SIGNAL ujadat

vegeredmeny:
IF szamlalo = 0 THEN
	SAY "A számtani közép nem értelmezhetô!"
ELSE
	SAY "A számok számtani közepe:" total/szamlalo
EXIT

hiba:
SAY "Helytelen adat!"
EXIT

A program egészen addig olvassa be és összegzi a total változóban a számokat, amíg ENTER-t nem ütünk. Ha nem számot gépelünk be, akkor hibajelzést kapunk. A bevitt adatok darabszáma a szamlalo változóban tárolódik, így amikor befejezôdött az adatok bevitele, az átlag a total és szamlalo változók közönséges osztásával számítható. Amennyiben a bevitt adatok száma 0, a program nem végzi el az osztást, mivel az hibát eredményezne.

A mûveletek kiértékelésének sorrendje

Láttuk, hogy bizonyos esetekben (kivonás, osztás) a végeredmény nagyban függhet a kiértékelés sorrendjétôl. Tovább bonyolítja a helyzetet, amikor a kiértékelendô kifejezésben több fajta operátor is jelen van. A kiértékelés sorrendje ilyenkor az operátorok közötti viszonytól is függ. Az alábbi táblázatban összefoglaltuk a REXX-ben használatos aritmetikai mûveletek egymáshoz viszonyított kiértékelési sorrendjét:

Operátor csoportOperátorRelatív kiértékelési sorrend
Unáris operátorok-, +Legelsô
Hatványozás**
Szorzás, osztás*, /, %. //
Összeadás, kivonás+, -Legutolsó

Egy kifejezés kiértékelésekor a REXX elôször azokat a mûveleteket hajtja végre, amelyek a listában feljebb állnak. Azonos rangú mûveletek esetében a kiértékelés balról jobbra történik. Tekintsük például az alábbi kifejezést:

ertek = 100 - 20 * 100 % 75

A szorzás és az osztás magasabb rangú, mint a kivonás, ezért elôször a 20 * 100 % 75 értékelôdik ki balról jobbra menet, mivel ezek viszont egyenrangú mûveletek. A részeredmény (26) aztán kivonásra kerül a 100-ból, s a végeredmény (74) az ertek változóban tárolódik el.

Egy kifejezés kiértékelése az operátorok egymáshoz viszonyított végrehajtási sorrendje miatt sok esetben nem ahhoz az eredményhez vezet, amit szeretnénk. Ilyenkor zárójelezéssel avatkozhatunk be a kiértékelési sorrendjébe, mivel elôször mindig a zárójelezett tagok kerülnek sorra. Zárójelezzük például a fenti kifejezést a következôképen:

ertek = (100 - 20) * 100 % 75

Ebben az esetben elôször a kivonás kerül végrehajtásra, majd a részeredmény (80) megszorzódik 100-zal, s az így kapott szám (8000) osztódik 75-tel, amelynek aztán az egész részét (106) kapja meg az ertek változó. Zárójelezett kifejezések önmaguk is tartalmazhatnak zárójelezett tagokat. Ebben az esetben mindig a legbelsô zárójel kerül legelôször feloldásra. Kövessük a kiértékelés sorrendjét az alábbi példán nyomon:

ertek = (99 - ((3 + 4) * (8 + 3))) / 11
ertek = (99 - (7 * (8 + 3))) / 11
ertek = (99 - (7 * 11)) / 11
ertek = (99 - 77) / 11
ertek = 22 / 11
ertek = 2


REXX GYÍK:

K1. A negálásnak és a kivonásnak ugyanaz a jele. Hogyan különbözteti meg a REXX ôket?
V1. A programértelmezô a szövegkörnyezet alapján dönti el, hogy melyik mûveletrôl van szó. Ez általában nagyon egyszerû feladat, mivel a negálás legtöbbször egy különálló lépésben történik: a = -b Az a = b - - c kifejezés esetében viszont a REXX-nek zárójeleznie kell, hogy végre tudja hajtani a mûveletet: a = b - (- c).


Gyakorlatok:

1. Értékelje ki a következô kifejezéseket!

a. 5 + 6 * 3
b. 100  2 % 5
c. (3 -  5) * -2
d. (5 + 3 * 4) * 2
c. 15 // 7 + 1

2. A következô program Zeller eljárásán alapulva kiszámítja, hogy egy adott dátumhoz a hét milyen napja tartozik (0 = hétfô ... 6 = vasárnap). Fejtse meg a program mûködését!

/* Gyakorlat 2 */

SAY "Gépeld be a dátumot a következô formában:"
SAY "Hónap nap év, pl.: 12 03 1996"
PULL honap nap ev
SAY honap'-'nap'-'ev"-hez tartozó nap száma:" Zeller()

EXIT

Zeller:
IF honap > 2 THEN
	DO
		kepzett_honap = honap - 2
		kepzett_ev    = ev
	END
ELSE
	DO
		kepzett_honap = honap + 10
		kepzett_ev    = ev - 1
	END

evszazad       = kepzett_ev % 100
ev_a_szazadban = kepzett_ev - 100 * evszazad
a_het_napja    = ((13 * kepzett_honap - 1) % 5 + nap +,
                 ev_a_szazadban + ev_a_szazadban % 4 - evszazad -,
                 - evszazad + 77) // 7
RETURN a_het_napja

3. A következô programban hiba van. Helyes mûködés esetén a program öt szám összegét számolja ki. Keresse meg a hibát!

/* Gyakorlat 3 */

bevitel:
IF count = 0 THEN
	SIGNAL kesz
count = count - 1
SAY "Kérek egy számot!"
PULL szam
total = szam + count
SIGNAL bevitel

kesz:
SAY "Az összeg:" total
EXIT

Kádár Zsolt
1997. 10. 19.
[ Elôzô lecke | Következô lecke | Tartalom ]