Wie haben die Apollo-Computer transzendente Funktionen wie Sinus, Arkustangens, Logarithmus ausgewertet?

Die Navigation mit einem Sextanten oder Manöver unter Verwendung von Kardanwinkeln könnten zwei Beispiele für Fälle sein, in denen ein Apollo-Computer Trigonometrie durchführen muss.

Trigonometrische Funktionen wie Sinus, Arkustangens usw. sind transzendent , ebenso wie Logarithmen. Sie können diese Funktionen nicht mit einem einfachen Ausdruck auswerten, der beispielsweise auf Multiplikation oder Division basiert, ohne zumindest einen iterativen Algorithmus.

Ein Techniker vor Ort würde einen Rechenschieber für zwei oder drei Ziffern nehmen und für weitere Ziffern in ein Buch mit trigonometrischen, logarithmischen und anderen Tabellen gehen. Zwischen zwei Zeilen könnten Sie noch mehr Ziffern von Hand interpolieren.

Aber wie werteten die Apollo-Computer transzendente Funktionen aus, oder wie wurden zumindest Berechnungen, die die Verwendung transzendenter Funktionen erforderten , in die Programme implementiert ?

Sind Sie sicher, dass Sie Trigonometrie für das Gimbaling durchführen müssen? Ich bin mir ziemlich sicher, dass es einfacher wäre, in der Vektormathematik zu bleiben, wenn Sie einen Linearantrieb verwenden. Wie auch immer, Trignonometriefunktionen werden normalerweise durch Tabellensuche implementiert oder als Taylor-Erweiterung angenähert . Keine Quelle, die direkt mit Apollo in Verbindung steht, tut mir leid.
... oder beides, die taylor-Erweiterung bereitet beim Start Lookup-Tabellen vor, falls der permanente Speicher weniger reichlich vorhanden ist als RAM.
@Christoph Der erste Satz beginnt mit zwei Instrumenten, die wahrscheinlich Winkeldaten erzeugen . Auch das, was in den 1960er Jahren mit Computern im Weltraum gemacht wurde, wird nicht durch die heutige Vorgehensweise abgedeckt. Ich werde das historyTag hinzufügen, um das noch klarer zu machen. Sie könnten auch überlegen, wo Tabellen gespeichert werden müssten, es gab herzlich wenig Speicher in den Apollo-Computern.
@Christoph schau mal hier: youtu.be/9YA7X5we8ng?t=1283 und auch hier youtu.be/YIBhPsyYCiM?t=273
@Christoph: Schon 1956 hatten wir einen besseren Algorithmus als Taylor, nämlich CORDIC. Ich weiß nicht, ob das in Apollo verwendet wurde.
Speicher (sowohl permanent als auch dynamisch) war sehr teuer, daher ist es nicht verwunderlich, dass sie keinen Tisch führten.
Dieselbe Frage könnte man zB Taschenrechnern oder wirklich jedem Computer stellen.
@Joshua bedenkt, dass diese in den frühen 1960er Jahren entwickelt wurden. In Anbetracht der Größen- und Gewichtsbeschränkungen für die Landung auf dem Mond und die Rückkehr zur Erde ist dies nicht nur "irgendein Computer". Tatsächlich halfen Technologien, die für Computer im Weltraumprogramm entwickelt wurden, ein Jahrzehnt später den Weg für „persönliche“ wissenschaftliche Taschenrechner zu ebnen. Es ist die Gesamtheit der Situation, die diese spezielle Frage zwingend macht.
@MSalters: CORDIC benötigt Tabellen mit Konstanten, etwa 50 Werte. Nicht sehr nützlich für die Apollo-Computer mit Kernseilspeicher für Programm und Konstanten.
@uhoh, ich stimme zu, dass die Gesamtheit der Situation überzeugend ist, aber das Fleisch der Antwort (Taylor-Erweiterungen) ist das gleiche, als ob ich fragen würde, wie mein Computer das macht, zumindest wie ich verstehe, dass diese Berechnungen heute passieren.
@Joshua Während moderne Implementierungen eine oder mehrere Taylor-Erweiterungen als Seed enthalten können (je nach Funktion ist die Sünde einfach, hier zu finden ), ist dies nur der Anfang, wie moderne Computer Transzendentale mit doppelter Genauigkeit ausführen. Was ich aus dieser Antwort gelernt habe, ist genau, wie es in diesem Fall gemacht wurde, der Grad der resultierenden Präzision (~ 1E-04), mit dem sie arbeiten mussten, der Aufwand, der in die Vor- und Nachskalierung geflossen ist und warum, und das Spartanische Kodierung.
@Joshua All dies ist einzigartig für die spezifischen Einschränkungen dieses speziellen, einzigartigen Computers. Zu Ihrer reduktionistischen Verwendung von „ist dasselbe wie“ kann ich nur sagen „nein ist es nicht“, worauf Sie mit „ja ist es“ antworten könnten, und wir könnten endlos weitermachen
@Joshua genau - jeder digitale Computer tut dies auf diese oder ähnliche Weise. Eine andere Sichtweise ist: "Woher stammen die Tabellen in den Büchern, in denen wir dieses Zeug nachgeschlagen haben?" Früher mussten einige arme Trottel diese Reihen von Hand und später mit Hilfe mechanischer Rechenmaschinen, die multiplizieren und dividieren konnten, durchrechnen. Das allgemeine Studiengebiet heißt "Numerische Methoden" und unter diesem Fachgebiet finden Sie leicht zahlreiche Bücher.
@JamieHanrahan, es gibt auch eine SE-Site! Zufälligerweise habe ich gerade gefragt, welchen Algorithmus Excel für Bessel-Funktionen verwendet (hat), die bei x = 8 unstetig sind?
@Uwe Eigentlich wurde CORDIC 1956 speziell für digitale Navigationscomputer in Flugzeugen entwickelt.
Für log ist es sogar möglich, den Wert an einen analogen Computer auszugeben, ihn zu berechnen und das Ergebnis in einen ADC zurückzulesen. Diese Dinge können in einem elektrischen Analogcomputer sehr schnell erledigt werden. Ich weiß nicht, ob es trigonometrisch funktioniert, aber ein mechanischer Analogcomputer kann das, wenn auch langsamer
@Cris Straton: Aus Wikipedia : "Wenn ein Hardware-Multiplikator verfügbar ist (z. B. in einem DSP-Mikroprozessor), sind Tabellensuchmethoden und Potenzreihen im Allgemeinen schneller als CORDIC". Der Apollo-Computer hatte eine ziemlich schnelle Multiplikation, Speicherzykluszeit: 11,7 Mikrosekunden. Additionszeit: 23,4 Mikrosekunden. Multiplikationszeit: 46,8 Mikrosekunden.
@phuclv: Es gab damals analoge elektronische Schaltungen für Logarithmus, Potenzierung, Addition, Multiplikation und Quadratwurzel, aber nicht für trigonometrische Funktionen wie sin, cos und tan.

Antworten (3)

Da sich der Apollo 11-Code auf GitHub befindet, konnte ich den Code finden, der wie eine Implementierung von Sinus- und Cosinus-Funktionen aussieht: Siehe hier für das Befehlsmodul und hier für den Mondlander (es sieht so aus, als wäre es derselbe Code).

Der Einfachheit halber hier eine Kopie des Codes:

 # Page 1102
            BLOCK   02

# SINGLE PRECISION SINE AND COSINE

            COUNT*  $$/INTER
SPCOS       AD      HALF            # ARGUMENTS SCALED AT PI
SPSIN       TS      TEMK
            TCF     SPT
            CS      TEMK
SPT         DOUBLE
            TS      TEMK
            TCF     POLLEY
            XCH     TEMK
            INDEX   TEMK
            AD      LIMITS
            COM
            AD      TEMK
            TS      TEMK
            TCF     POLLEY
            TCF     ARG90
POLLEY      EXTEND
            MP      TEMK
            TS      SQ
            EXTEND
            MP      C5/2
            AD      C3/2
            EXTEND
            MP      SQ
            AD      C1/2
            EXTEND
            MP      TEMK
            DDOUBL
            TS      TEMK
            TC      Q
ARG90       INDEX   A
            CS      LIMITS
            TC      Q       # RESULT SCALED AT 1.

Der Kommentar

# SINGLE PRECISION SINE AND COSINE

zeigt an, dass das Folgende tatsächlich eine Implementierung der Sinus- und Kosinusfunktionen ist.

Informationen über den verwendeten Assemblertyp finden Sie auf Wikipedia .

Teilerklärung des Codes:

Das Unterprogramm SPSINrechnet tatsächlich Sünde ( π x ) , und SPCOSrechnet cos ( π x ) .

Die Subroutine SPCOSaddiert zuerst eine Hälfte zur Eingabe und fährt dann mit der Berechnung des Sinus fort (dies ist gültig wegen cos ( π x ) = Sünde ( π ( x + 1 2 ) ) ). Das Argument wird am Anfang des SPTUnterprogramms verdoppelt. Deshalb müssen wir jetzt rechnen Sünde ( π 2 j ) Pro j = 2 x .

Die Subroutine POLLEYberechnet eine nahezu taylorische polynomische Approximation von Sünde ( π 2 x ) . Zuerst speichern wir x 2 im Register SQ (wobei x bezeichnet den Eingang). Daraus wird das Polynom berechnet

( ( ( C 5 / 2 x 2 ) + C 3 / 2 ) x 2 + C 1 / 2 ) x .
Die Werte für die Konstanten befinden sich im selben GitHub-Repository und sind

C 5 / 2 = .0363551 ( π 2 ) 5 1 2 5 ! C 3 / 2 = .3216147 ( π 2 ) 3 1 2 3 ! C 1 / 2 = .7853134 π 2 1 2

die wie die ersten Taylor-Koeffizienten für die Funktion aussehen 1 2 Sünde ( π 2 x ) .

Diese Werte sind nicht exakt! Das ist also eine Polynom-Näherung, die der Taylor-Näherung sehr nahe kommt, aber noch besser ist (siehe unten, auch dank @uhoh und @zch).

Schließlich wird das Ergebnis mit dem DDOUBLBefehl verdoppelt, und die Subroutine POLLEYgibt eine Annäherung an zurück Sünde ( π 2 x ) .

Bezüglich der Skalierung (erst halbieren, dann verdoppeln, ...) erwähnte @Christopher in den Kommentaren, dass die 16-Bit-Festkommazahl nur Werte von -1 bis +1 speichern könne. Daher ist eine Skalierung erforderlich. Hier finden Sie eine Quelle und weitere Details zur Datendarstellung. Details zur Montageanleitung finden Sie auf der gleichen Seite.

Wie genau ist diese Fast-Taylor-Näherung? Hier sehen Sie ein Diagramm auf WolframAlpha für den Sinus, und es sieht nach einer guten Annäherung für aus x von 0,6 zu + .6 . Hier ist die Kosinusfunktion und ihre Näherung aufgetragen . (Ich hoffe, sie mussten nie den Kosinus für einen Wert berechnen π 2 , denn dann wäre der Fehler unangenehm groß.)

@uhoh hat einen Python-Code geschrieben , der die Koeffizienten vergleicht C 1 / 2 , C 3 / 2 , C 5 / 2 aus dem Apollo-Code mit den Taylor-Koeffizienten und berechnet die optimalen Koeffizienten (basierend auf dem maximalen Fehler für π 2 x π 2 und quadratischer Fehler in diesem Bereich). Es zeigt, dass die Apollo-Koeffizienten näher an den optimalen Koeffizienten liegen als die Taylor-Koeffizienten.

In diesem Diagramm die Unterschiede zwischen Sünde ( π x ) und die Annäherungen (Apollo/Taylor) werden angezeigt. Man sieht, dass die Taylor-Näherung viel schlechter ist x .3 , aber viel besser für x .1 . Mathematisch ist dies keine große Überraschung, da Taylor-Approximationen nur lokal definiert sind und daher oft nur in der Nähe eines einzelnen Punktes (hier x = 0 ).

Beachten Sie, dass Sie für diese Polynomnäherung nur vier Multiplikationen und zwei Additionen benötigen ( MPund ADim Code). Für den Apollo Guidance Computer standen Speicher und CPU-Zyklen nur in geringer Stückzahl zur Verfügung.

Es gibt einige Möglichkeiten, die Genauigkeit und den Eingabebereich zu erhöhen, die für sie verfügbar gewesen wären, aber dies würde zu mehr Code und mehr Rechenzeit führen. Beispielsweise hätte das Ausnutzen der Symmetrie und Periodizität von Sinus und Cosinus, die Verwendung der Taylor-Entwicklung für Cosinus oder das einfache Hinzufügen weiterer Terme der Taylor-Entwicklung die Genauigkeit verbessert und auch beliebig große Eingabewerte ermöglicht.

Ich lese mich ein, aber es ist nicht einfach, weil ich mit der Programmiersprache nicht vertraut bin. Auf den ersten Blick sieht es wie eine Taylor-Annäherung aus, aber ich bin mir nicht sicher. Ich werde bearbeiten, wenn ich mehr habe.
Ich bin dabei ... ich denke, es hat mit der Skalierung zu tun.
Die Skalierung ist darauf zurückzuführen, dass mit einfacher Genauigkeit nur Werte von -1 bis +1 gespeichert werden können :). Die Genauigkeit liegt bei etwa 13 Bit, was zum Typ mit einfacher Genauigkeit passt (16 Bit, von denen eines das Vorzeichenbit und eines ein Paritätsbit ist, auf das Software nicht zugreifen kann).
Oh Gott ... Ich habe seit dem College keine Montage mehr gesehen, ich kann mir nicht vorstellen, einen ganzen Leitcomputer schreiben zu müssen, der nur OP-Codes und Low-Level-Funktionen verwendet. Auch willkommen in der SE, brillante Antwort.
@Christoph Also gehe ich davon aus, dass es sich um eine Festkommadarstellung und nicht um eine Gleitkommadarstellung handelte, richtig? Haben Sie auch einen Link, den ich der Antwort hinzufügen kann (oder den Sie bearbeiten können)?
@uhoh: Die Skalierungsprobleme sind jetzt behoben, und ich habe Diagramme eingefügt, um die Funktion mit der Annäherung zu vergleichen. Es scheint für einige Werte zu passen.
Ich habe diese Informationen im Virtual AGC Programmer's Manual gefunden .
Zum Thema: Fehlerdiagramm . Der maximale Fehler innerhalb der Domäne liegt bei etwa 0,0001
@supinf Oh, ich habe die ganze Zeit beobachtet, wie sich Ihre Antwort entwickelt. Der Wolfram-Alpha-Link ist ebenfalls hilfreich, um das Ausmaß der Vorher-Nachher-Skalierung zu verstehen. Ausgezeichnete Mathe- und Code-Ermittlung!
@MagicOctopusUrn Die meisten Leute auch nicht. Abgesehen von Leuten, die es zum Spaß machen, ist ASM heute mehr oder weniger auf Reverse Engineering, Leute, die Compiler machen, und die Art von eingebetteten Plattformen mit extrem niedrigen Kosten/Fähigkeiten/Leistung beschränkt, bei denen die Arbeit genauso viel EE wie CS ist.
Was zusätzlich ordentlich ist, es ist besonders genau in der Nähe der (häufig verwendeten) 0, 30 und 60 Grad.
Gute Antwort. Man kann eine transzendente Funktion algebraisch nicht genau berechnen, aber es gibt Annäherungen, die für die Technik gut genug sind. Rechenschieber und Tabellen sind auch nicht exakt.
„Ich hoffe, sie mussten nie den Kosinus für einen Wert ≥ π/2 berechnen.“ Es ist nicht notwendig, die Beziehung cos(π - α) = -cos(α) zu verwenden. Unter Verwendung dieser und ähnlicher Beziehungen muss nur der Bereich 0 ≤ α ≤ π/4 berechnet werden. Diese Transformationen können für sin, cos, tan und cot verwendet werden. Es kann andere Funktionen innerhalb des Apollo 11-Codes geben, die diese Transformationen verwenden, wenn größere Argumente möglich sind.
Tolle Analyse! Ich hatte noch nie viel Erfolg beim Versuch, AGC-Assembly selbst zu lesen. Willkommen an Bord.
Nett! Das bringt mich dazu, meinen eigenen AGC-Emulator zu schreiben und auszuprobieren :-)
Könnten einige der Anweisungen in der Nähe des Starts 2x auf den Bereich +/-1 abgeschnitten und dann invertiert worden sein, wenn das umbrochen wird? In diesem Fall wäre das Verhalten von cos() für jeden Winkel sauber gewesen.
@MagicOctopusUrn Die Brogrammer unter uns, die behaupten, dass „Mädchen nicht programmieren können“, sollten zur Kenntnis nehmen, dass dieser Code von einer Frau entwickelt wurde .
Taylor basiert auf Ableitungen in einem einzigen Punkt, es ist keine beste Anpassung (minimaler maximaler Fehler) über einen Bereich. Es wird also erwartet, dass ähnliche, aber unterschiedliche Polynome verwendet würden.
@philipp Ich habe tatsächlich eine kleine Arbeit über sie geschrieben – das Bild von ihr, wie sie neben einem Stapel Montageprogrammen steht, die größer ist als sie selbst, hat mich immer inspiriert. Das Programmieren erfordert eine bestimmte Verdrahtung des Gehirns, imo keinen bestimmten Personentyp :).
Meine Arithmometerwerte gehen durch die Decke!
@supinf in der Tat scheinen die Koeffizienten so optimiert zu sein, dass sie gute Ergebnisse über ± π / 2 liefern. Eine schnelle Überprüfung ergibt fast die gleichen Zahlen wie im Programm und nicht die Nominalwerte einer richtigen Taylor-Erweiterung bei x = 0. pastebin.com/UnVudQs4 Übrigens sehr aufschlussreiche Antwort, nochmals vielen Dank!
@Philip: Dieser Code wurde von einem Team aus hauptsächlich Männern und wenigen Frauen unter der Leitung von Magaret Hamilton entwickelt. Sie hat hier nicht gesagt , ob sie die einzige Frau im Team war.
@uhoh Also, was sie getan haben, war viel besser als die Taylor-Annäherung (@zch hat dies bereits vorgeschlagen). Ich habe Ihren Python-Code bearbeitet und auch verlinkt. Großartige Analyse – sie zeigt, dass ihnen der mittlere quadratische Fehler wichtiger war als der maximale Fehler.
@supinf das Pastebin-Skript (reimt sich auf Abfalleimer) war nur ein schneller Test. Minimierung kann überraschend knifflig sein und ich habe mir nicht die Zeit genommen, sie gründlich zu untersuchen, also habe ich Ihre Diskussion über die Ergebnisse etwas zurückgenommen. Danke!
Ich hoffe, dass ich eines Tages so helfen kann. Überall in meinem Kopf für jetzt. Sehr demütigend.
Die Wahl des C als Konstante ist ein moderater Hinweis darauf, dass das fragliche Polynom keine Taylor-Entwicklung ist, sondern eine Quadratur-Entwicklung in Chebyshev-Polynomen oder ähnlichem.
@EP: Daran hatte ich nicht gedacht, aber ich war neugierig, wie die Funktion einen so großen nützlichen Bereich zu haben schien, da meine eigene Erfahrung mit Taylor-Reihen darauf hindeutete, dass der nützliche Bereich viel kleiner ist. Das Akzeptieren eines Genauigkeitsverlusts an Punkten nahe Null ermöglicht jedoch weiter entfernte Punkte, viel genauer zu sein.
@uhoh Da sind die Minimierungsprobleme konvex und es kommt auch die Meldung es'Optimierung erfolgreich beendet.' bei resmrs und resmax war ich von den ergebnissen ziemlich überzeugt. Auch maxiter und maxfev wurden nicht erreicht. Aber zumindest ist klar, dass die Apollo-Koeffizienten viel besser sind als die Taylor-Koeffizienten
@supinf-Algorithmen sind nicht perfekt, und wir können zu 100% auf ihre Perfektion vertrauen, bis wir einmal gebissen werden . Das Optimierungsmodul bietet eine große Anzahl sehr unterschiedlicher Algorithmen zur Auswahl. Ich denke, der nächste Schritt wäre, mehrere auszuprobieren und einfach zu sehen wie nahe ihre Ergebnisse beieinander liegen, oder in diesem Fall, um es analytisch zu testen, um zu sehen, ob es sich zumindest um ein lokales Maximum handelt. Endliche Größe von x array könnte es auf skurrile Weise nicht konvex machen, die minimierte Funktion könnte nicht glatt sein (diskontinuierlicher Gradient).
@supinf space.stackexchange.com/questions/31102/… ist eine weitere verwandte Frage, wenn Sie das auch erklären möchten :).
@Uwe Auf dieser Seite werden Autoren einzelner AGC-Unterprogramme gutgeschrieben - obwohl ich männlich bin, sehe ich 5 wahrscheinlich weibliche Namen auf der Liste. ibiblio.org/apollo
@supinf Ich habe eine weitere Frage zum AGC-Code, falls Sie interessiert sind. space.stackexchange.com/q/31196/195
@NathanTuggy Was die Welt jetzt mehr denn je braucht, sind "bessere Klammern" ;-)
Ich frage mich, wie dieser Code in NASM aussieht ... zur Projektliste hinzugefügt.
@Philipp Ich kann nicht sehen, wie der Kommentar von Magic Octopus Urn, auf den Sie antworten, angeblich impliziert, dass "Mädchen nicht programmieren können", noch irgendein anderer Kommentar von denen, die ich bisher auf dieser Site gelesen habe. Assembler-Code seit der College-Zeit nicht mehr gesehen zu haben, bedeutet auch nicht unbedingt, dass man ein "Brogrammer" ist, was auch immer das bedeutet. Nicht zuletzt ist es ziemlich unvernünftig anzunehmen, dass diese Codebasis vollständig von einer einzigen Person geschrieben wurde, egal ob es sich um einen Mann oder eine Frau handelt, und durch diese Annahme die Zeit und den Aufwand des gesamten Programmierteams außer Acht zu lassen .
@Philipp Aus diesen Gründen scheint der Hauptzweck Ihres Kommentars darin zu bestehen, eine Art Off-Topic-Rhetorik in Bezug auf Identitätspolitik abzugeben, anstatt nützliche und konstruktive Informationen zu teilen, und ich finde das in diesem Zusammenhang ziemlich unangemessen und Einstellung.

Sie haben auch nach dem Logarithmus gefragt, also machen wir das auch. Im Gegensatz zu den Sinus- und Kosinusfunktionen wird diese nicht nur mit einem Taylor-Reihen-ähnlichen Ansatz implementiert. Der Algorithmus basiert auf dem Verschieben der Eingabe und dem Zählen der Anzahl der Verschiebungen, die erforderlich sind, um den erforderlichen Maßstab zu erreichen. Ich kenne den Namen dieses Algorithmus nicht, diese Antwort auf SO beschreibt das Grundprinzip.

Die LOGImplementierung ist Teil des CGM_GEOMETRY -Moduls und gekennzeichnet

SUBROUTINE ZUR BERECHNUNG DES NATÜRLICHEN LOGS

Die Routine verwendet die NORMAssembler-Anweisung, die laut ihrer Dokumentation die Zahl im Akkumulator ("MPAC"-Register) nach links verschiebt, bis sie mit einem Wert endet 0,5 und „fast 1 " [1] , und schreibt die Anzahl der durchgeführten Schiebeoperationen in die als zweites Argument angegebene Speicherstelle (die mathematische Bedeutung der linken Schiebeoperation ist binäre Potenzierung 2 n , Exponenten im Argument eines Logarithmus können als Faktoren ausgedrückt werden und Produkte im Argument können als Additionen ausgedrückt werden, also die Vereinfachung von l n ( 2 c s c a l e d ) hinein c c Ö n s t + l n ( s c a l e d ) funktioniert, wo c ist die Schichtzahl und c Ö n s t ist der vorberechnete Wert von l n ( 2 ) ).

Dann verwendet es ein Polynom dritten Grades zur Annäherung l n in diesem Intervall mit fest codierten Koeffizienten [3] :

Geben Sie hier die Bildbeschreibung ein

Schließlich wird die zuvor erhaltene Verschiebungszahl wieder multipliziert (mal die Konstante 0,0216608494 [2] , unter Verwendung von SHORTMP).

Der Optimierungsdruck muss so hoch gewesen sein, dass sie das umgekehrte Vorzeichen nicht behoben haben, bevor sie aus der Subroutine zurückkehrten, sondern von allen Aufrufstellen verlangten, dies stattdessen zu berücksichtigen.

Anwendung des Logarithmus-Unterprogramms:
zum Beispiel als Teil der Reichweitenvorhersage in der Wiedereintrittssteuerung.

---

[1] Das Speicherformat für eine Zahl mit doppelter Genauigkeit wurde aus zwei 16-Bit-Wörtern aufgebaut, wobei das MSB von jedem das Vorzeichen ist und eine Einerkomplementdarstellung des Bereichs bildet 1 < x < 1 aber das LSB ist ein Paritätsbit. Wir haben es also mit einem 30-Bit-Format zu tun, das zwei Vorzeichenbits enthält, was einige Kopfschmerzen bei der Emulatorimplementierung verursacht.

[2] die ACG-Assemblersprache lässt CLOG2/32als Identifikatornamen zu. Dies verursachte einige weitere Kopfschmerzen bei der Implementierung des Emulators .

[3] Wie wurden die Koeffizienten gefunden? Code- Kommentare zur Montageliste des interpretativen Trignonometriemoduls (ja, Astronauten konnten das ACG dazu bringen, dynamische Anweisungen zu interpretieren) legen nahe, dass die Methode auf Arbeiten von C. Hastings basierte, insbesondere Approximations for Digital Computers. Princeton University Press, 1955 . Das komplexeste Polynom dieser Art in ACG ist eines der siebten Ordnung, gleicher Modul, der zu berechnen ist a r c c Ö s ( x ) 1 x P ( x ) ).

Ich vermute, dass die Gleichung ln(arg) = ln((2^a)*b) = a*ln(2) + ln(b) verwendet wird. a ist die Anzahl der Verschiebungen, die benötigt wird, um 0,5 < b < 1 zu erhalten, sodass arg = (2^a)*b. Aber es sollte eine Konstante ln(2) = 0,693147 geben, die ich nicht finden konnte. Aber ln(2)/32 = 0,02166 liegt nahe an der Konstante 0,0215738898. 32 * 0,0215738898 ist 0,69036.
auf den zweiten Blick handelt es sich um ein Polynom. Zeile 274 wertet ein Polynom dritten Grades (Zeile 276, 2+1) mit folgenden Koeffizienten 0,031335467 usw. aus. Ich werde das nachahmen und eine Handlung hinzufügen, wenn ich später Zeit habe.
@Uwe Die Konstante für ln ( 2 ) / 32 ist in Zeile 302 vorhanden.
0,0216608494 * 32 ist tatsächlich 0,693147181. Ich kämpfe immer noch mit diesem seltsamen Double-Precision-Complement-with-Overflow und Parity-Speicher, komme mit einer versuchten Emulation in C noch nicht in die Nähe.
@uhoh So sieht es für mich aus 0,031335467 ( 1 x ) + 0.0130145859 ( 1 x ) 2 + 0.0215738898 ( 1 x ) 3 ist eine gute Annäherung an ln ( x ) / 32 Pro x zwischen 0,5 und 1 .
@Litho: guter Fund in Zeile 302. Ich hätte unten mehr suchen sollen. Erstaunlicherweise sind alle 9 Ziffern der Konstante gleich wie bei meinem alten hp32S berechnet. Eine 30-Bit-Konstante kann bis zu 9 Dezimalstellen enthalten, sodass nur die letzte Dezimalstelle 4 in der binären Darstellung verloren geht.
@Litho ja, schön!
@dlatikay Ich habe eine weitere Frage zum AGC-Code, falls Sie interessiert sind. space.stackexchange.com/q/31196/195
Zu Ihrer Information, ich habe gerade gefragt, wie der Apollo-Leitcomputer mit Paritätsbitfehlern umgegangen ist.

Eine Ergänzung zur Antwort von @supinf :

a) Die Initiale DOUBLEinSPT

b) Überläufe für Eingang x (Register A) über +0,5 (+90°) und Unterläufe für x unter -0,5 (-90°). In diesem Fall Aist >+1 oder <-1 und im Folgenden wird TSder korrigierte Wert gespeichert (effektiv eins addiert, wenn er unter -1 liegt, oder eins subtrahiert, wenn er über +1 liegt) TEMKund Aauf +1 gesetzt ( Überlauf) oder -1 (Unterlauf). Außerdem wird der Sprung TCFzu POLLEYignoriert.

c) XCHvertauscht TEMKmit A, Aenthält also jetzt den korrigierten Wert und TEMK±1.

d) INDEXAddiert den Wert von TEMK(±1) zum Wert der nächsten ADAnweisung, die stillschweigend Überläufe korrigiert. Da LIMITSgleich -0,5 ist, ergibt sich im Überlauffall eine Addition von 0,5 (-0,5 + +1 = 0,5) und im Unterlauffall eine Subtraktion von 0,5 (-0,5 + -1 = -1,5 = -0,5) .

e) COMnegiert den Wert von A– dazu gehört auch das Invertieren des Overflow-Bits – und

f) das Finale ADaddiert eins im Überlauffall und subtrahiert eins im Unterlauffall. ADführt vor der Addition keine Überlaufkorrektur durch und setzt danach das Überlauf-Flag. Jeder übergelaufene Wert (>+135° und <-135°) kommt also wieder in den Bereich [-1,+1].

Visualisierung der Berechnungen af

Wenn dies ADunter/überläuft (ich sehe keine Möglichkeit, dass dies passieren könnte), wird es Aauf ±1 gesetzt, springt auf ARG90und wird Aauf -( LIMITS+ A) gesetzt, was -(-0,5+1)=-(+0,5)=-0,5 Zoll ist im Überlauffall und -(-0,5-1)=-(-1,5)=-(-0,5)=+0,5 im Unterlauffall. Ich dachte zunächst, dies würde für x > +135° oder x < -135° passieren, aber das scheint nicht der Fall zu sein.

Aber diese Anpassung des Gehäuses <-90° und>+90° sieht für mich irgendwie falsch aus. Ich würde erwarten, dass die Linie f von (+0,5, +1,0) bis (+1,0, +0,0) und von (-0,5, -1,0) bis (-1,0, -0,0) reicht. Das wäre der Fall, wenn COMdirekt XCHohne Schritt d folgt.

Bitte korrigieren Sie mich, wenn ich einige Teile falsch mache, ich habe diesen Code erst kürzlich gesehen und versucht, ihn mit dem AGC-Befehlssatz herauszufinden .