Je einfacher die Aufgabe auf den ersten Blick ist, desto weniger denkt der Entwickler darüber nach, wie sie richtig implementiert werden soll, und der Fehler, der im besten Fall gemacht wird, wird im schlimmsten Fall spät entdeckt - er wird überhaupt nicht bemerkt. Es geht um eine dieser Aufgaben, nämlich die Teilung und Skalierung in Steuerungen, die ausschließlich ganzzahlige Arithmetik unterstützen.
Warum Anwendungsprogrammierer unter den Bedingungen einer solchen Arithmetik nicht auf die Komplexität der Berechnung achten, ist eine Frage. Ich wage nur zu behaupten, dass die Gewohnheit, Berechnungen auf dem Taschenrechner durchzuführen, aller Wahrscheinlichkeit nach Auswirkungen hat ... Auf jeden Fall kann ich mit beneidenswerter Regelmäßigkeit "Ich habe das Glück" sehen, wie die Kollegen im Geschäft auf denselben Rechen treten. Dieses Material zielt darauf ab, den gleichen "Rechen" zu neutralisieren.
In der Ganzzahlarithmetik besteht das Ergebnis der Division einer Ganzzahl durch eine andere aus zwei Zahlen - dem Quotienten und dem Rest. Wenn wir den Rest der Division verwerfen, erhalten wir das Ergebnis in absoluten Werten, gerundet auf eine kleinere ganze Zahl.
Bei der Realisierung von Berechnungen mit Brüchen wird dieser Moment oft übersehen, und nachdem sie ihn verpasst haben, erhalten sie Verluste in der Genauigkeit der Berechnungen. Darüber hinaus nimmt die Genauigkeit der Berechnungen mit zunehmendem Wert des Teilers ab. Zum Beispiel ergibt 53/13, 64/13 4, obwohl der Quotient der Teilung der zweiten Fraktion tatsächlich viel näher an 5 liegt.
Tatsächlich ist es einfach, das Ergebnis auf das nächste Ganze zu runden. Zu diesem Zweck reicht es aus, den Rest der Division zu verdoppeln, ihn mit sich selbst zu summieren und ihn dann erneut durch dieselbe Zahl zu dividieren, durch die er ursprünglich geteilt wurde, und den Quotienten aus dieser Division zu dem Quotienten zu addieren, der aus der anfänglichen Divisionsoperation erhalten wurde.
Im ersten einfachen Beispiel werde ich am Beispiel der Berechnung des Verhältnisses zweier Größen zeigen, wie eine solche Rundung in Software implementiert ist
Unter Berücksichtigung der Tatsache, dass solche Berechnungen im Programm möglicherweise wiederholt erforderlich sind, implementieren wir den Berechnungsalgorithmus in einem Format, das zum Packen in ein Unterprogramm geeignet ist.
Für die korrekte Ausführung der dafür notwendigen Zwischenberechnungen wird ein Array von fünf Registern benötigt, wir werden es mit dem Begriff TEMP [0..4] bezeichnen. Warum fünf und nicht weniger, werde ich etwas tiefer erklären.
Aktionsalgorithmus:
1. TEMP[2]= A 2. TEMP[3]= B ----- 3. TEMP[0,1]= TEMP[2]/TEMP[3] 4. TEMP[1,2]= TEMP[1]*2 5. TEMP[4]= 0 6. TEMP[1..4]= TEMP[1,2]/TEMP[3,4] 7. TEMP[0]= TEMP[0]+TEMP[1] ----- 8. Y= TEMP[0]
Die Schritte 3 bis 7 können in eine Unterroutine verschoben werden.
Falls gewünscht, kann das Ergebnis direkt aufgezeichnet werden, indem TEMP [0] mit TEMP [1] außerhalb des Berechnungsunterprogramms summiert wird. Dies ist prinzipienlos. Das Einzige, was zu beachten ist, ist, dass bei vielen der gleichen Art von Berechnungen das Entfernen der Operation zum Hinzufügen zum Hauptteil des Programms zu einer Erhöhung des von ihm verwendeten Programmspeichers führen kann.
Warum wurden für die Zwischenberechnung bis zu 5 Register benötigt? Und die Operation des Summierens des Restes der Division für sich, wie bereits erwähnt, wird durch Multiplizieren des Restes mit zwei ersetzt? Sehr einfach - um mit einem unbegrenzten Satz von ganzen Zahlen zu arbeiten.
Lassen Sie mich erklären: Wenn wir zum Beispiel die Zahl 32767 durch -32768 im Rest teilen, erhalten wir 32767, und das Ergebnis seiner Addition wird zweifellos über den Bereich der ganzen Zahl hinausgehen.
Das heißt, der doppelte Rest einer ganzzahligen Division eines Bruchs im Interesse der Rundung des Ergebnisses einer solchen Division sollte immer im doppelten ganzzahligen Format dargestellt werden.
Fortsetzung folgt...