Register
Das Rechnen in der FLEX-Sprache, Teil 2 (erst ab V27.2)
Rechenbefehle mit arithmetischen Ausdrücken
Zum Ausprobieren:
Rechenbefehl selber eingeben -- Umrechnungen -- Verzinsung -- Tilgung
Es gibt zwei Formen: (beide auch für acon)
eval rechenbefehl
und
Z=rechenbefehl
Der rechenbefehl wird als arithmetischer Ausdruck interpretiert und das Ergebnis im ersten Fall in die interne Variable kopiert, im zweiten Fall in die "interne Zahl" (beschrieben in Teil 1 ).
(Mit dem kleinen z, dem "internen Zähler", geht es nicht!)
Das Ergebnis ist immer eine Zahl mit Dezimalpunkt, Nullen am Ende werden entfernt.
Wenn hinter dem Punkt nur Nullen stehen, wird der Punkt auch entfernt - eine Zahl mit Punkt am Ende sähe nicht gut aus.
Wenn rechenbefehl fehlt, wird der Inhalt der iV genommen. Man kann also auch zuerst mittels var in der iV einen beliebigen Rechenbefehl zusammensetzen und diesen dann auswerten lassen.
Gleich ein Beispiel zum Ausprobieren: In #upr steht ein Betrag, es soll dazu die Mehrwehrtsteuer ausgerechnet werden.
Z=0.19 * #upr
var "19% von " #upr " sind " Z " EUR"
mes
Das einfachste Rezept zum Rechnen ist also: zuerst mit Z=... die Zahl ausrechnen, dann mit var ... Z ... in eine Zeichenfolge einbauen.
Regeln
Ein rechenbefehl ist eine Folge von Elementen mit Operatoren dazwischen:
elem op elem op ... elem
Jedes op ist einer der Operatoren + - * / ^
für Addition, Subtraktion, Multiplikation Division und Potenzierung.
Leerzeichen links und rechts davon sind nicht nötig, auch nicht bei dem = im Z-Befehl.
Ein elem kann sein:
· eine Zahl. Negative Zahlen beginnen mit -, positive aber nicht mit +
Sehr große und sehr kleine Zahlen kann man in Exponentialdarstellung schreiben: z.B.
1E15 bzw. 1E-20. Auch e statt E möglich.
Weitere Beispiele: 5e+3 = 5000, 75E-4 = 0.0075, 4.81E6 = 4810000
· eine Feldangabe #nnn oder #nnn$x, wobei #nnn auch eine #u-Variable sein kann. Es ist nicht notwendig, daß ein solches Feld nur eine Zahl enthält, sondern das Programm wird sich die Zahl selbst heraussuchen, wenn z.B. Buchstaben davor oder Klammern darum herum stehen. Stehen allerdings zwei Zahlen drin, wird nur die erste genommen. (Die Manipulationsbefehle, die es bei var gibt, sind hier nicht anwendbar, siehe aber Beispiel 3.)
Beispiel: 19% vom Betrag in #9DB$p: Z=#9DB$p * 0.19
· Eine freie Variable $Abc, auch hier bei Bedarf mit Unterfeld-Code: $Abc$d (freie Var. ab V31.7 auch bei acon )
· einer der internen Zahlenwerte z oder Z. [Bis V27.1 waren dies die einzigen Rechenvariablen]
Zu beachten:
· Wenn ein Element nicht existiert oder keine Zahl enthält, wird als Wert 0 angenommen. Keine Fehlermeldung!
· Wenn am Ende noch ein op steht, hat das keine Wirkung.
· Dezimalzahlen können mit Komma oder Punkt angegeben werden, das Ergebnis hat immer einen Punkt (falls es nicht eine Ganzzahl ist).
· Das Ergebnis ist immer eine Zahl ohne E-Darstellung.
· Bei Zahlen mit mehr als 14 Stellen wird das Ergebnis hinter der 14. Stelle ungenau. Jedoch ist beim Rechen mit realen Zahlen eine Genauigkeit von mehr als 14 Stellen ohne praktischen Belang.
· Wenn man Division durch 0 verlangt, erhält man ein Ergebnis mit ca. 300 Stellen, das für alle praktischen Belange so gut wie unendlich groß ist. Auch hier keine Fehlermeldung oder gar Absturz!
· Die Abarbeitung erfolgt von links nach rechts, also ohne Priorität der Operatoren!
· Klammerung ist nicht möglich. Stets kann man statt dessen zuerst zwei oder mehr Zwischenergebnisse bilden und in Variablen lagern, die man am Ende in geeigneter Weise miteinander verrechnet. Am bequemsten ist Z: statt (a+b)*(c+d) könnte man z.B. schreiben:
Z=a+b\eval c+d*Z // a+b ausrechnen, dann mit c+d malnehmen
· Maximale Länge des Befehls? 250 Zeichen. Das wäre aber recht unübersichtlich, man teilt dann die Rechnung besser auf zwei oder mehr Zeilen auf.
· Potenzen: Z.B. 2^8 für 2 hoch 8; #uxa^2 erhebt den Wert in #uxa zum Quadrat
· Wurzeln: Z.B. 2^0.5 bzw. 2^0.3333333 für Quadrat- bzw. Kubikwurzel aus 2 (2 hoch 1/2 bzw. 1/3).
· Den Divisionsrest beim Dividieren ganzer Zahlen kann man mit dem "internen Zähler" z ausrechnen. Das Rezept dafür steht in der betr. Dokumentation zum internen Zähler.
· Rundung? Wer z.B. nur 2 Nachkommastellen braucht, verfährt so, wobei die letzte Stelle dann gerundet ist:
eval ...
Z=
var Z2
Das ist gerade dann hilfreich, wenn das Ergebnis ein Geldbetrag sein soll. Es fallen dann auch keine Nullen am Ende weg, sondern .00 bleibt stehen.
Hinweis: Rechenbefehle kann man nur mit den Befehlen eval ... und Z=... auswerten, nicht innerhalb von var- oder write-Befehlen o.a. Das Ergebnis einer Rechnung muß also zuerst in eine Variable oder Z, diese kann anschließend angezeigt oder ausgegeben werden.
Hinweis:
Fertige Anwendung: Umrechnen verschiedener Einheiten. Der FLEX umrech.flx führt die Sache aus, die Auswahlliste umrech.vw (auf HELP) kann leicht erweitert werden um weitere Umrechnungen.
Beispiel 1:
Wenn man in #uzy einen Zähler hat und diesen um 1 erhöhen und dann prüfen will, ob die Zahl 100 erreicht ist, macht man dies so:
eval #uzy+1
ins #uzy
if =100 jump xyz
Beispiel 2:
Aufgabe: Betrag im Teilfeld $p von #9DG in Euro umrechnen
eval #9DG$p/1.95583
Damit wird der Zahlenwert im Unterfeld p von #9DG genommen und durch 1.95583 dividiert.
Beispiel 3:
Aufgabe: In #95 sei am Ende, immer hinter einem Semikolon, eine Preisangabe. Diese soll man auf die Variable #upr aufaddieren.
Hier muß man den arithmetischen Ausdruck zuerst per var zusammenstellen, weil man mit eval nicht die Manipulationsbefehle zur Verfügung hat, um z.B. hinten am Ende den Teil hinter dem Semikolon herauszugreifen.
var #95(T";") " + " #upr
eval
ins #upr
Beispiel 4:
Aufgabe: Dasselbe, aber die gesamte aktuelle Ergebnismenge durcharbeiten und dann die Gesamtsumme anzeigen.
Dazu erweitern wir die Sache um eine Schleife:
#upr 0
first
:loop
var #95(T";") " + " #upr
eval
ins #upr
next
if yes jump loop
var "Gesamtsumme: " #upr
mes
Beispiel 5:
Aufgabe: Celsius in Fahrenheit umrechnen und umgekehrt. Dies ist eingebaut in den Beispiel-FLEX umrech.flx
:beginn
ask Temperatur?
if "" end
ins #ute
z=
Celsius -> Fahrenheit
Z=z*1.8+32
mit 1 Nachkommastelle
var Z1
ins #utf
Fahrenheit -> Celsius
Z=z-32*5/9
var Z1
ins #utc
Zeile aufbereiten
var #ute(0,r3) "C = " #utf(0,r5) "F" n #ute(0,r3) "F = " #utc(0,r5) "C" n
mes
jump beginn