Pascal-Programm aus Astronomie mit dem PC

Status
Es sind keine weiteren Antworten möglich.

Berthold

Neues Mitglied
Hallo, liebe Wissende,
neben vielen anderen Sachen interessiere ich mich seit meiner Schulzeit, die schon einige Jahrzehnte her ist, auch für Astronomie. Gerade bin ich dabei, die Pascal-Programme aus "Astronomie für den Personal Computer" in PureBasic zu portieren. Dieses Buch scheint in diesen Kreisen gut bekannt zu sein, wenn man sich die Foreneinträge ansieht.
Nun stoße ich beim Portieren auf die Schwierigkeit, dass in dem Programm "NEWMOON", das auch die Unterprogramm "MDJ" und "CALDAT" benötigen, die Variable "B_MOON" nirgends mit einem Wert geladen wird. Wenn ich auch nicht die einzelnen mathematischen Ausdrücke des Programms verstehe, so kann ich doch den Programmablauf nachvollziehen. Nach meiner Logik hat die Variable "B_MOON" im Hauptprogramm immer den Wert 0 (Null). Und nur dort ist sie zu finden.
Liege ich richtig, oder verstehe ich die Programmiersprache Pascal nicht. (Ein wenig bin ich durch den Unterstrich im Namen dieser Variablen irritiert, obwohl ich in Beschreibungen von Pascal nichts diesbezügliches gefunden habe.)
WRITELN (' Datum':16,'UT':7,'Breite':11); WRITELN;
WRITELN (' h':23,'o':9);

LUNATION_0 := TRUNC( D1 * (YEAR_CALC-2000)/100 );
FOR LUNATION_I := LUNATION_0 TO LUNATION_0 + 13 DO
BEGIN
T_NEW_MOON := ( LUNATION_I - D0 ) / D1;
IMPROVE ( T_NEW_MOON, B_MOON );
IMPROVE ( T_NEW_MOON, B_MOON );
MJD_NEW_MOON := 36525.0*T_NEW_MOON + 51544.5;
CALDAT ( MJD_NEW_MOON, DAY,MONTH,YEAR,HOUR );
IF YEAR=YEAR_CALC THEN
WRITELN(DAY:10,MONTH:3,YEAR:5,HOUR:6:1,B_MOON:9:1)

Herzliche Grüße aus Mecklenburg
Berthold
 
Hallo!

Einer der Autoren dieses Buches ist gelegentlich auf diesem Forum aktiv (https://forum.astronomie.de/members/thomas_pfleger.852/). Vielleicht antwortet er ja auf eine persönliche Nachricht?

> (Ein wenig bin ich durch den Unterstrich im Namen dieser Variablen irritiert, obwohl ich in Beschreibungen von Pascal nichts diesbezügliches gefunden habe.)

Diesbezüglich gibt es meines Wissens keine Konvention von Pascal-Seite. Das ist der jeweiligen Vorliebe des Programmierers überlassen, ob er SprechendeVariablenNamen oder Sprechende_Variablen_Namen oder (FORTRAN-Style-mässig) SPVANA verwendet ;)

Viele Grüße
Maximilian
 
Servus,

oh Gott... Pascal :eek: das hatte ich in der Realschule und erfolgreich verdrängt :D bin aber seit ein paar Jahren als Programmierer (Automatisierung) tätig.

Evtl. ein paar Tipps:

Ist die Variable in den jeweiligen Programmen auch deklariert? Wird die Variable an die Unterprogramme übergeben?

Viele Grüße
Mathias
 
Hi,

"...oder (FORTRAN-Style-mässig) SPVANA..." :cool::y:

Schon länger her bei mir. Variablen, die im PASCAL Hauptprogramm deklariert sind, stehen in allen Subroutines ebenfalls mit Namen und Wert zur Verfügung, ohne das man sie explizit an eine Subroutine übergeben muß (Global Variables). In Subroutines deklarierte Variablen sind aber nur lokal dort verfügbar (Local Variables).

Die Underlines sind rein optisch, sie haben keine sprachinterne besondere Bedeutung.

Grüße, Gerd
 
Hallo Berthold,

schaue Die die Procedure improve einfach mal an. In der Deklarationszeile stehen die übergebenen
Parameter als "VAR" ("procedure improve (VAR t,b:Real);"). Das heißt also, dass hier nicht nur der Wert
der Variablen übergeben, sondern eine Referenzierung stattfindet.
Zu Deutsch: beim Aufruf von "improve (t_new_moon,b_moon)" werden die *Variablen* "t_new-moon" und
"b-moon" an die Procedure übergeben und nicht nur die Werte der Variablen. In der Proceduren-Deklaration
heissen diese Variablen dann "t" bzw. "b" (s.O.). Dann wird in der Procedure improve etwas berechnet und
am Ende den Variablen "t" und "b" ein Wert zugewiesen. Im aufrufenden Programm wird dann der Wert von
"t" nach "t_new_moon" bzw. "b" nach "b_moon" übergeben. Demnach verändern sich die Werte der beiden
Variablen nach dem Aufruf der procedure improve.

Als anschauliches Beispiel für so eine "VAR"-Parameterübergabe nehme ich immer die
"Procedure Tausche (VAR a,b:Integer);
var hilf:integer;
begin
hilf:=a;
a:=b;
b:=hilf;
end;"
-->
Nach dem Aufruf von:
x:=4; y:=12; Tausche (x,y);
erwarte ich, das die Werte von x und y vertauscht sind. Eine bloße Übergabe der Werte
"Procedure Tausche (a,b:Integer);" --> also ohne "VAR a,b:integer" würde das nicht können, x und y hätten
die selben Werte wie vor dem procedure-Aufruf, trotz das in der procedure haargenau das Selbe steht.

Der Underscore ist, wie oben schon gesagt, einfach eine Möglichkeit einen Namen besser zu strukturieren.
In Pascal darf eine Variable sogar mit einem "_" beginnen (oder mit einem Buchstaben, jedoch nicht mit
einer Ziffer).


Gruß,
Jürgen
 
Hallo... ich nochmal ;-) ...
Die Fachbegriffe nach denen Du suchen kannst sind "call by value", also ohne "VAR" und "call by reference",
sprich mit "VAR".


Gruß,
Jürgen
 
Hallo, an alle, die geantwortet haben,
zunächst herzlichen Dank für die schnellen Beiträge. Besonderen Dank an @Bingoin . Du hast bei mir einiges zum Verständnis des Programms (und von Pascal) beigetragen. Das mit dem Unterstrich (_) habe ich zwar vermutet, aber nicht gewusst! Das sind so die Feinheiten der Programmiersprachen. In PureBasic zum Beispiel kann ich in einer Prozedur nur einen Wert wieder an das aufrufenden Programm übergeben, aber auch ein Array, oder ich deklariere Variablen als Global. … aber das wollt Ihr gar nicht wissen! … Mit dem Übergeben von Variablen und Werten ist es eben nicht so einfach, wie mit den Grundrechenarten und den Schleifen, die in allen Sprachen sehr ähnlich sind …
Dass eine 1:1-Portierung nicht möglich ist, war mir jedenfalls schon von Anfang an klar.
Herzlichen Dank
Berthold
PS: Als Dankeschön ein kleines Gedicht von mir, das in diesen Rahmen passt:
(Ich hoffe, dass das hier als Ausnahme nicht stört.)

Österliche Rechenkunst
März 2016

Der Computus, so hör' und staune,
Entstammte der Antike Laune.
Im Mittelalter war er der Test,
Zu ermitteln uns das Osterfest.

Ein Freitag war’s, an dem Jesus starb,
Schon am Sonntag wieder leer das Grab.
Der Frühlingsvollmond, er zeigte sich,
Zur Auferstehung wonniglich.

Neunzehn Jahre, des Mondes Zirkel,
Und Frühlingsanfang im Gewirke,
Sonnenzyklus und das Schaltejahr
Sonntagsletter, Mathe-Inventar
Ist im Verfahren inklusive.
Das war die neue Perspektive.

Abt Dionysius hat’s entdeckt,
Es in Ostertafeln reingesteckt.
Im Jahre Fünfhundert-zwanzig-sechs
Wurd’s gebilligt durch den Pontifex.

Ostertagsberechnung galt als Kunst,
Einzig Mathe in der Uni Gunst,
Bis Carl Friedrich Gauß hat sich getraut,
Eine Osterformel aufgebaut,
Die das Volk kann für sich verwenden
Oder als App dem Smartphone spenden.
 
Hallo Sternfreunde,
diese Anfrage habe ich erst jetzt entdeckt. Vielen Dank an alle, die bereits so schnell und mit guter Erklärung geantwortet haben.
Jaja, lange ist es her. Müsste ich heute was in Pascal schreiben, könnte ich das nicht mehr. Bin inzwischen fast ausschließlich mit Java unterwegs.
Viele Grüße
Tom
 
Hallo Berthold,

freut mich, das ich Dir helfen konnte :-) .
Bin wie gesagt kein Basic-ler und deshalb auch nicht so syntax-fest, aber ich habe im Netz das hier gefunden:

Hier wird gezeigt, wie man (ähnlich wie in C) Parameter per Referenz übergeben kann (also mit Pointern,
gekennzeichnet mit 'nem "*").
Für's grobe Verständnis kann man sich das so vorstellen, dass bei "call by value" der aktuelle Wert bzw. die
aktuellen Werte der Variablen im Aufruf gelesen werden und dann an die Procedure-Variablen übergeben werden.
Beim "call by reference" wird/werden die *Adresse(n)* der Variablen an die Procedure übergeben. Beschreibe
ich im Unterprogramm die Variable an dieser Adresse(n), so ändert sich sofort der Wert der entsprechenden
Variablen, welche ich im Hauptprogramm (oder von wo ich die Procedure aufrufe) im Aufruf angebe.
Du kannst in der Proceduren-Deklaration natürlich auch "call by value" und "call by reference"-Variablen mischen,
so wie es benötigt wird.
Wenn Du also alle Pascal-"VAR"-Variablen in Basic mit "*" versiehst und im Programm so behandelst bzw. alle
Pascal-nicht-VAR-Variablen als "normale" Basic-Variablen schreibst, solltest Du eine Pascal-Procedure schon ohne
unsaubere Tricksereien ;-) in Basic umschreiben können.

Als Übung und zum Verständnis lege ich Dir nochmal die Tausche-Procedure von oben nahe. Einfach mal ein paar
Print-Anweisungen in die Procedure und in das Hauptprogramm einstreuen und gucken, was mit welcher Deklaration
an Variablenwerten rauskommt.

Gruß,
Jürgen
 
Zuerst das Positive:
@Thomas_Pfleger : Ich hatte nicht im Entferntesten daran geglaubt, dass ich hier einen Autor von "Astronomie mit dem Personal Computer" 'treffen' würde. Vielen Dank für die Antwort!
Das Pascal-Programm "NEWMOON" funktioniert nun endlich in der PureBasic-Variante, allerdings nicht ohne ein paar Hürden und leider nur auf 2 Tage genau (Zwischen 1980 und dem Jahre 2000 allerdings sogar auf ein paar Stunden genau).
Im Pascal-Code steht im Buch in einem Kommentar sinngemäß, dass an dieser Stelle die Unterprogramme MDJ und CALDAT einzugeben sind und es wird danach die Variable T als in julian. Jahrh. seit J2000, T=(JD-2451545)/36525) beschrieben. Einen Aufruf von CALDAT habe ich im Code gefunden, jedoch keinen für MDJ, sodass ich etwas probieren musste. Schließlich habe ich festgestellt, dass die Eingabe von YEAR_CALC in das julianische Datum gewandelt werden muss und der Variablen T zugeordnet werden muss. Danach ergaben die ausgegebenen Daten einen Sinn.
Wenn es interessiert, werde ich demnächst das (aufgehübschte) PureBasic-Programm NEWMOON hier online stellen.
Herzlichen Dank an alle die mir geholfen haben.
Berthold
 
Zuletzt bearbeitet:
Hallo Berthold,

die Funktion CALDAT im besagtem Buch wandelt das Modifizierte Julianische Datum wieder in ein Kalenderdatum zurück. Die astronomischen Berechnungen werden ja nicht direkt mit einem Kalenderdatum gemacht, es wird zuerst aus dem Kalenderdatum das Julianische Datum berechnet (JD) bzw. bei Montenbruck/Pfleger das modifizierte julianische Datum (MJD). Warum hier das MJD verwendet wurde hab ich nie ganz kapiert, vielleicht weil es einfach kleinere Zahlen sind. Hat vielleicht auch mit der Fließkomma-Arithmetik auf "damaligen Computern" zu tun....:cool:

Das JD und MJD unterscheiden sich wie folgt:

MJD = JD - 2400000.5

MJD = 0.0 entspricht dem 17. November 1858 00:00 UT. Es gibt also die Zahl der seit diesem Datum vergangenen Tage an.

Bei vielen Berechnungen verwendet man dann den Parameter T (manchmal auch klein t) als Argument mit

T = (JD - 2451545.0) / 36525.0

bzw.

T = (MJD - 51544.5) / 36525.0

Das sind die Julianischen Jahrhunderte seit der Epoche J2000. T ist dann negativ vor J2000 bzw. positiv danach.
(Ein Julianisches Jahrhundert hat 36525 Tage)

Die Berechnungen laufen dann sinngemäß etwa so ab:

=> Kalenderdatum mit Jahr, Monat, Tag, Stunde, Minute, Sekunde
=> Umwandeln in JD oder MJD (Die Funktion heißt bei Montenbruck/Pfleger auch "Mjd")
=> Berechnen von T
=> Mit T wird dann irgendwas astronomisches berechnet, Sonnen-/Mond-/Planetenposition, Ekliptikschiefe, Äquinoktien/Solstitien ....was auch immer
=> Bei Positionen erhält man natürlich die Koordinaten zurück
=> Bei Berechnungen die einen Zeitpunkt ausrechnen erhält man das JD bzw. MJD zurück
=> Mit CALDAT wird (hier) dann wieder in ein lesbares Kalenderdatum samt Uhrzeit zurück verwandelt.

So ungefähr...

Zur Variablen Moon_B vermute ich, dass es sich einfach um die ekliptikale Breite des Mondes handelt, die ja ausschlaggebend bei der Suche nach Sonnenfinsternissen (Neumond) bzw. Mondfinsternissen (Vollmond) ist.

cs,
harald

--
 
Zuletzt bearbeitet:
Status
Es sind keine weiteren Antworten möglich.
Zurück
Oben