TGI Praktikum |
Implementierung |
Um das Programm zu starten muss es zuerst mit dem Turbo C-Compiler TCC kompiliert und gelinkt werden.
Dies geschieht mit folgendem Aufruf: tcc getlg.c lg.asm .
Danach lässt sich das Programm getlg.exe ausführen.
Der verwendete Compiler und die Quellcodes sind im Downloadbereich verfügbar.
Quellcode und Erklärung von lg.asm |
.MODEL SMALL, C .386 public lg public origlg .DATA EINS DQ 1.0 ; Konstante 1.0 ZWEI DQ 2.0 ; Konstante 2.0 LN2 DQ 0.693147180559945 ; Konstante ln(x) LN2DIVLN10 DQ 0.301029995663981 ; Konstante ln(2)/ln(10) m DQ ? ; Variable für Mantisse e DQ ? ; Variable für Exponent k DQ 1.0 ; Index k (Anfangswert 1.0) bruch DQ ? ; Bruch (m-1)/(m+1) bruchhochk DQ ? ; Bruch ((m-1)/(m+1))^k summe DQ ? .CODE lg proc near push bp ; Register sichern push cx mov bp, sp fld qword ptr [bp+6] ; Argument x auf FPU-Stack laden fxtract ; Aufteilen in Mantisse m und Exponent e fstp m ; (Hinweis: 1 <= m <= 2) fstp e fld m ; (m-1) berechnen fld EINS fsub fld m ; (m+1) berechnen fld EINS fadd fdiv ; (m+1)/(m-1) auf FPU-Stack fst bruch ; bruch = (m+1)/(m-1) ; Wert bleibt auf FPU-Stack! fst bruchhochk ; da k am Anfang = 1, ist bruchhochk = bruch ; Wert bleibt immer noch auf FPU-Stack! fstp summe ; erster Eintrag für summe = bruch mov cx, 11 ; es folgt eine Schleife, die 11 mal wiederholt wird schleife: fld bruch ; bruchhochk = bruchhochk * bruch * bruch fld bruch fld bruchhochk fmul fmul fst bruchhochk ; Wert bleibt noch auf FPU-Stack fld k ; k um 2 erhöhen fld ZWEI fadd fst k ; neues k bleibt auf FPU-Stack fdiv ; st(0) = bruchhochk / k fld summe ; summe = summe + (bruchhochk / k) fadd fstp summe loop schleife fld summe ; st(0) = summe * 2 fld ZWEI fmul fld LN2 ; st(0) = ln(2) fdiv ; st(0) = ln(2) * (summe * 2) fld e ; st(0) = e fadd ; st(0) = log2(x) = e + st(1) fld LN2DIVLN10 fmul ; st(0) = lg(x) = (ln(2) / ln(10)) * st(1) pop cx ; Register freigeben pop bp ret lg endp ; Hier die Originalfunktion der FPU: origlg proc near push bp ; Register sichern push cx mov bp, sp fld qword ptr [bp+6] ; Argument x auf FPU-Stack laden fld1 ; 1 auf FPU-Stack fxch ; st(0) und st(1) vertauschen fyl2x ; Logarithmusfunktion fldl2t fdiv pop cx ; Register freigeben pop bp ret origlg endp end |
Die eigene Routine lg richtet sich nach der unserer 3. Methode der Spezifikation (s. Formeln).
Zuerst wird das Argument aufgeteilt in Exponent und Mantisse. Für die Mantisse wird dann der natürliche Logartithmus mittels der (nicht alternierenden) Reihe entwickelt. Für die Anzahl der Schleifenwiederholungen legen wir uns auf 11 fest. Diese Entscheidung stützt sich auf einen Programmtest mit Abbruchbedingung für Verfeinerungswerte die kleiner als 10^-15 waren. Dies war immer nach 10 bis 11 Wiederholungen der Fall.
siehe hierzu auch folgene Tabelle:
Quellcode getlg.c |
/* TGI Praktikum Assembler - Gruppe 160 */ /* getlg.c - Berechnet den ln(x) ber den log zur Basis 2 */ extern double lg(double x); /* eigene Logarithmusfunktion */ extern double origlg(double x); /* Originalfunktion der FPU */ main() { double x; printf("Berechnung der Funktion y=lg(x)\n"); printf("Bitte Argument x eingeben : "); scanf("%lf", &x); if (x <= 0) { printf("Fehler: log ist nur für Werte > 0 definiert!"); } else { printf("eigene Funktion ergibt y = %.14f\n", lg(x)); printf("Originalfunktion der FPU ergibt y = %.14f\n", origlg(x)); } return(0); } |
grafische Implementierung |
Die Bildschirmausgabe zeigt einen Ausschnitt unserer Funktion:
Auch dieser Quellcode ist unter Download verfügbar.
zurück | 23.06.00 Katrin Stedele, Rainer Schmoll, Tanja Wojak |