2. Tipps und Tricks  Teil 4  (Stand: 24.10.2007)

Bedienungsanleitung und Befehlsliste können beim Programmieren am PC mit Taste F1 aufgerufen werden.

Zahlenbereich Überschreitung von 32767 beim Rechnen, Begrenzen       

Zählen_bis_65535 im word, Zahl  0 bis 65535, Anzeigen mit 1 bis 2 Kommastellen

Zahlen_über_65535  Zähler, Addition, Multiplikation, Division NEU


Phantasie ist wichtiger als Wissen.  (Albert Einstein)

2.4.0) Define für Teil 4

define Wert1 byte [3]  ' Byte 3 Zwischenspeicher 1

define Wert2 byte [4]  ' Byte 4 Zwischenspeicher 2

define Wert12 word[2] ' = Byte 3,4 (Überlappung mit Bytes Wert1 und Wert2)

define wert1Bit0 Bit [17] ' für bit-Handling des byte Wert1 (Zwischenspeicher)

define wert1Bit1 Bit [18]

define wert1Bit2 Bit [19]

define wert1Bit3 Bit [20]

define wert1Bit4 Bit [21]

define wert1Bit5 Bit [22]

define wert1Bit6 Bit [23]

define wert1Bit7 Bit [24]

nach_oben

2.4.1) Überschreitung des Zahlenbereichs beim Rechnen

1.      Überschreitung beim Addieren im Bereich 0 bis 65535

Wert12 = 32000

Wert12 = wert12 + 20000 ' Ergebnis 52 000

Das  Ergebnis ist eine negative Zahl in ccBasic (-19232), weil das vorderste Bit als Minuszeichen interpretiert wird.

Sie kann aber auch als positive Zahl bis 65535 interpretiert werden. Zahlenausgabe siehe unten.

2.      Begrenzen bei Addition und Zählern  0 bis 65535 (anstelle –32768 bis +32767)

(1) Begrenzen beim Rückwärtszählen bei Null

If  Zaehler > 0 then  Zaehler = Zaehler  - 1 

Null  wird nicht unterschritten (sonst würde 65535 entstehen, -1  in ccBasic)

(2) Begrenzen bei Subtraktion

If  Zaehler – wert > 0 then Zaehler = Zaehler – wert  else  Zaehler = 0

Die Subtraktion wird nicht ausgeführt, wenn es zur Unterschreitung von Null käme.

(3) Begrenzen beim Vorwärtszählen bis +65535

Aufwändiger ist die Begrenzung beim Addieren

Zaehler = Zaehler + 1  '  65535 darf nicht überschritten werden (65536 wäre 0)

Die Zahlenreihe lautet in ccBasic mit der Interpretation bis 65535 in Klammern:

+32766, +32767, -32768 (+32768), -32767 (+32769), -32765 (+32770),....,-2 (65534), -1 (+65535)

Zur Begrenzung kann man den halben Zählerwert abfragen:

If  (Zaehler SHR 1 AND &h7FFF) < 32767 then Zaehler = Zaehler + 1  '  begrenzt auf 65535

If  65535 / 2 < 32767 then ... ist der Beweis in Zahlen, dass die Addition nicht ausgeführt wird.

(4) Begrenzen bei Addition

Bei größeren Werten als +1 muss als Begrenzung von 32766 der halbe Wert abgezogen werden.

Bei variablen Werten gilt:

If  (Zaehler SHR 1 AND &h7FFF) < (32766 – wert / 2) then Zaehler = Zaehler + wert  '  begrenzt auf 65535 -wert

Die Addition wird nicht ausgeführt, wenn es zu einer Überschreitung käme.

Man kann als Ersatz den maximalen Wert 65535 setzen, indem else angehängt wird.

If ... then .... else  Zaehler  = -1  '  65535 ist bei ccBasic  die Zahl  -1 (Minus Eins)

3.      Dividieren  von Zahlen bis 65535

Das Programm arbeitet im gesamten Zahlenbereich 0 bis 65535.

In diesem Beispiel wird 52000 durch 10 geteilt. Hierbei wird 10 zerlegt in 2 und 5.

Wert12 = 52000 ' in ccBasic -19232

' Erst wird erst durch 2 geteilt (das Minus entfernt) und dann durch 5.

wert12 = wert12 SHR 1 : wert1Bit7 Bit = 0  ' Ergebnis 26000

wert12 =  wert12 / 5   ' Ergebnis 5200

(wert12 SHR 1 AND &h7FFF) für Teilen durch 2 und Entfernen von Minus kann auch angewendet werden.

Ist der Nenner eine ungerade Zahl oder könnte als Variable gerade oder ungerade sein, so muss in zwei Stufen gerechnet werden.

In diesem Beispiel wird 52000 durch 11 geteilt.

Hierbei wird erst durch 2 geteilt, dann durch 11 und danach wieder mit  2 multipliziert.

Wert12 = 52000 ' in ccBasic -19232

wert12 = wert12 SHR 1 : wert1Bit7 Bit = 0  ' Ergebnis 26000

wert12 =  wert12 / 11 * 2  ' Ergebnis 4726 statt 4727

mit Rundungsroutine „+ halber Nenner“ (siehe unten) lautet die letzte Zeile

wert12 = wert12 / 11 + (wert12 + 11) / 11  ' Ergebnis  4727

Diese hier abgewandelte Rundung ist jedoch nicht 100%ig richtig.

4.      Überschreitung beim Multiplizieren (Zerlegung eines Faktors)

Wird das Ergebnis beim Multiplizieren größer 32767 , muss ein Faktor zerlegt werden.

Das Verfahren kann im  Zahlenbereich 0 bis 65535 benutzt werden.

Beispiel: 1002 * 43 = 43086 soll auf LCD ausgegeben werden.
Zerlegung: 43 / 10 = 4 und 43 MOD 10 = 3
Multiplikation: 1002*4 und 1002*3 (= 4008 und 3006)
Ergebnis:
4 Stellen sind 4008 + 3006/10 = 4308
Einer ist 3006 MOD 10 = 6

define     nach_oben

5.      Überschreitung beim Multiplizieren (Nenner dividieren)

Nutzungsgrad = 100* Eindauer / GesamtZeit  '  als Prozentzahl

Wenn (100* Eindauer) die Zahl 32767 überschreitet, entsteht ein unsinniges Ergebnis.

Dies ist bei Eindauer = 328 Minuten bereits der Fall.

Lösung :

Nutzungsgrad = Eindauer / (GesamtZeit / 100) ' als  Prozentzahl

Die Prozentzahl kann auch gebildet werden, indem der Nenner  (Klammer beachten) durch 100 geteilt wird.

Dieses Verfahren ist besonders zweckmäßig, wenn die Zeit in Minuten oder Sekunden gemessen wird.

6.      Überschreitung beim Multiplizieren (variabler Faktor)

Nutzungsgrad = 100* Eindauer / GesamtZeit  '  als Prozentzahl

Wenn (100* Eindauer) die Zahl 32767 überschreitet, entsteht ein unsinniges Ergebnis.

Dies ist bei Eindauer = 328 Minuten bereits der Fall.

Lösung :

If  Eindauer > 327 then wert3 = 10 else wert3 = 1

Nutzungsgrad = 100 / wert3 * Eindauer / (GesamtZeit / wert3)

Wert3 ist ein Zwischenspeicher (define wert3 byte), der auch für andere Rechnungen benutzt wird.

Ab Eindauer 328 wird der Wert 100 durch 10 dividiert. Die Multiplikation ergibt nun nur 3280.

Als Ausgleich wird im Nenner auch durch 10 dividiert (Klammer beachten).

Sinngemäß ist bei der Nachkommastelle zu verfahren (siehe oben Bewertung des Modulowertes):

Rest    = 100 / wert3 * Eindauer MOD (GesamtZeit / wert3) '  Rest ohne Bewertung

Für Komma 1-stellig gilt, falls (GesamtZeit / wert3) *10  nicht 32767 überschreitet:

wert2  = 100 / wert3 * Eindauer MOD (GesamtZeit / wert3) *10 / (GesamtZeit / wert3)

7.      Überschreitung beim Multiplizieren (Byte-Zerlegung)

Beispiel: 3000 * 15 = 45000 überschreitet 32767 und soll in ein word gespeichert werden.

Die Zahl 3000 wird aufgeteilt in High- und Low-Byte (Linkes und rechtes Byte)

Linkes Byte 3000 / 256 = 11  rechtes Byte 3000 MOD 256 = 184

Nun wird mit beiden Bytewerten multipliziert. 11 * 15 und 184 * 15

Linkes Byte beträgt 11*15 + 184*15 / 256 '  Ergebnis 175

Rechtes Byte beträgt 184*15 MOD 256 '  Ergebnis 200

Bei der Ausgabe als word wird die Zahl über 32767 als eine negative Zahl gezeigt.

Die folgende Zahlenausgabe würde das Ergebnis zeigen 45000 (= 175 * 256 + 200)

nach_oben

2.4.2) Zahlenausgabe ohne Vorzeichen 0 bis 65535 (statt –32768 bis 32767)

Beispiel: Ein Zähler (word) kann auch über 32767 hinaus zählen. Die Zahl wird nun von der c-control negativ interpretiert.

Man kann aber weiter zählen bis 65535. Wie kann man nun die Zahl anzeigen?

Define Zaehlerwert  word 

Die Zahl wird durch 10 geteilt, indem mit dem Befehl „Schiebe Rechts 1 Bit“ durch 2 geteilt, das Minus durch Maskierung entfernt und dann durch 5 geteilt wird.

Die Teilung der Zahl beim Einer hat den Vorteil, dass keine führende Null ausgegeben werden muss.

Außerdem hat man eventuell direkt die Einer als Kommastelle.

Zahl4 = ( Zaehlerwert SHR 1 AND &h7FFF)  / 5 '  4 Stellen

Einer = (( Zaehlerwert + 32768) MOD 10 + 18) MOD 10 '  1 Stelle (evt. Kommastelle)

Braucht man 2 Kommastellen, dann muss bei deren Ausgabe beachtet werden, dass eine führende Null für 0 bis 9 notwendig ist.

Zahl3 = ( Zaehlerwert SHR 1 AND &h7FFF)  / 50 '  3 Stellen

Zahl2 = (( Zaehlerwert + 32768) MOD 100 + 168) MOD 100 ' 2 Stellen

Zum Testen kann man anstelle Zaehlerwert  den Timer 0 bis 65535 anzeigen lassen.

2.4.3) Überschreiten des Zahlenbereichs beim Zählen (größer 65535)

Noch größere Zahlen kann man durch  Übertrag auf einen zweiten Zähler erhalten z.B. 999 999 oder 2 559 999.

Define ZaehlerA word

Define ZaehlerB byte

Beispiel: if Ereignis then goto Zaehlen  else goto Ende

#Zaehlen

if ZaehlerA  = 9999 then goto Uebertrag ' nur bis 4 Stellen zählen

ZaehlerA = ZaehlerA + 1 : Goto Ende ' 4 Stellen

#Uebertrag

ZaehlerB = ZaehlerB + 1 : ZaehlerA = 0 ' 5. und 6. Stelle (möglich bis 255)

#Ende ' Ergebnis ZaehlerB enthält die 5. und 6. Stelle (0 bis 99) und ZaehlerA enthält 4 Stellen.

Die Zahlen sind bereits dezimal sortiert.

Deshalb kann die große Zahl auf LCD oder mit Terminalprogramm leicht ausgegeben werden, indem nach ZaehlerB sofort ZaehlerA folgen kann.

Noch größere Zahlen siehe nächster Abschnitt „Addieren“.

Natürlich kann der Übergang auch bei 32767 erfolgen, doch sind dann Rechnen und  Zahlen-Ausgabe schwierig.

ZaehlerA = ZaehlerA + 1  ' ZaehlerA bis 32767

If  ZaehlerA >=  0 then goto  Ende ' (wenn Zaehler negativ wird)

ZaehlerB = ZaehlerB + 1 : ZaehlerA = 0 ' (erfolgt der Übertrag auf  ZaehlerB)

#Ende '                                                                                                                                 

2.4.4) Überschreiten des Zahlenbereichs beim Addieren (größer 65535)

Beim Beispiel wird statt einer Variablen ein fester Wert (371) addiert.

Beispiel: if Ereignis then goto Addieren  else goto Ende

#Addieren

ZaehlerA = ZaehlerA + 371 ' erst addieren

if ZaehlerA  < 1000 then goto Ende ' 3 Stellen überschritten ?

ZaehlerB = ZaehlerB +  ZaehlerA / 1000 ' Übertrag von ZählerA

ZaehlerA = ZaehlerA  MOD 1000 ' 3 Stellen

#Ende

ZaehlerB enthält Tausender und ZaehlerA enthält 3 Stellen (Hunderter, Zehner und Einer).

Die maximale Zahl beträgt 255 999, wenn ZaehlerB als byte definiert wurde. Bei ZaehlerB als word kann die Zahl 32 767 999 werden.

Nutzt man zusätzlich die Ausgabe ohne Vorzeichen beträgt die maximale Zahl 65 535 999.

ZählerA darf natürlich auch 4 Stellen ( /10000) enthalten. Dann sind die Grenzen 2 559 999 bzw. 655 359 999.

nach_oben

2.4.5) Dividieren von Zahlen (größer 65535)

Die Zahl 386 780 liegt in diesem Beispiel wieder in ZaehlerB ( 0 bis 255) und ZaehlerA (0 bis 9999).

ZaehlerB = 38 '  Wert *10000 = 380000

ZaehlerA = 6780 ' 4 Stellen max 9999

Diese  Zahl  386780 soll durch 3 geteilt werden. Das Ergebnis muss also 128926 sein.

ZaehlerA = ZaehlerA / 3 + 10000 / 3 * ZaehlerB  MOD 3 ' = 6780 / 3 + 10000/3*2 = 8926

ZaehlerB = 38 / 3 '  = 12 Rest 2

 

2.4.6) Überschreiten des Zahlenbereichs beim Multiplizieren (größer 65535)

Das Prinzip der Zerlegung eines Faktors siehe obige Beispiele Multiplikation bis 65535.

Beispiel: 6315 * 93 = 587 295

Die Zahl darf im word nur 32767 betragen. Deshalb wird die Zahl 6315 zerlegt beispielsweise in 63 Rest 15.

WertB = 6315 / 100 * 93 + 6315 MOD 100 * 93 / 100 ' Hunderter mit Übertrag von Rest

63 * 93 + 15 * 93 /100 = 5859 + 13 = 5872

WertA = 6315 MOD 100 * 93 MOD 100 ' Rest 2 Stellen

15* 93 MOD 100 = 95

Das maximale Ergebnis der Multiplikation darf  3 276 700 betragen mit beliebigen Faktoren.

Bei noch größeren Zahlen müssen beide Faktoren (hier x und y) zerlegt werden in Hunderter und Rest.

x * y = (Hx + Rx) * (Hy + Ry)

Für Anwender bereits fertig ausmultipliziert:

 = Hx * Hy + Rx * Hy + Hx * Ry + Rx * Ry

Hunderter mit Summe aller Überträge der Reste

WertB = ((x / 100 * y / 100) /100 + (x MOD 100 * y / 100) /100

              + (x /100 * y MOD 100) /100 + (x MOD 100 * y MOD 100) /100

Zunächst Summe aller Reste, dann Rest 2 Stellen

WertA = ((x / 100 * y / 100) MOD 100 + (x MOD 100 * y / 100) MOD 100 +

              + (x /100 * y MOD 100) MOD 100 + (x MOD 100 * y MOD 100) MOD 100 ) MOD 100  

 

--------------------  ENDE    Tipps und Tricks  Teil 4  ------------  nach_oben

-----------------   zurück zu   Tipps Teil 1                      Tipps_und_Tricks_Teil_2                        Startseite     

 

 

Kostenlose Zähler und Statistiken für Ihre Website bei www.motigo.com