allegro-Homepagehttp://www.allegro-c.deallegro-C
BlueChyp
V27.2
BlueChyp
Neuer- und Verbesserungen

7. Mai 2007







Mehr zu den Themen:


 

 

a99 : Rechnen 

In a99 eingeben:  h xeval

 

Das Rechnen in der FLEX-Sprache  (ab V27.2)

Rechenbefehle mit arithmetischen Ausdrücken

 

 

 Es gibt zwei Formen: (beide auch für  avanti)

eval rechenbefehl       avanti   

 und

Z=rechenbefehl       avanti 

 

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

(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, desgl. 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. nicht bei avanti )

·       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 die Zahl 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: X umrech eingeben. 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

 

 

 

 

 


http://www.allegro-c.de/bluechyp/



Bernhard Eversberg, UB Braunschweig 2007-05-03