¿ Funktion als Parameter ?

06/04/2009 - 21:14 von count zero | Report spam
Ich verwende den free pascal Kompilierer.

#v+
[richard@localhost bin]$ fpc Zinseszins.pas
Free Pascal Compiler version 2.2.2 [2008/10/26] for i386
Copyright (c) 1993-2008 by Florian Klaempfl
Target OS: Linux for i386
Compiling Zinseszins.pas
Linking Zinseszins
298 lines compiled, 0.1 sec
[richard@localhost bin]$
#v-

Sind in den Beriechen mit (*¿¿¿¿¿.?????*)
die Funktionen die eine Funktion_als_Parameter
haben für Standard Pascal richtig?

Das kann zur Zeit der verwendte fpc noch nicht!

In den Bereichen mit (*¡!¡!¡.!¡!¡!*) und nachfolgend
ist/sind Funktion(en) mit Funktion(en)_als_Parameter
diese habe ich versucht nachzubilden.

Die Funktion(en) mit Funktion(en)_als_Parameter ist
das fogende korrekt, lesbar,...?

#v+

{$Mode fpc}

Program Zinseszins;

uses math; // Funktion x^y; intpower(x,y)

(*¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡*)
type
Typ_Funktion_Zinsfaktor =
function
(prozent: single;
Anzahl: byte
): extended;
(*¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡*)

var
Geld: Currency;
Zinsfusz: single; // Zinsfuß in % angeben
Zinsanzahl: byte;
rdtsc_anfang, rdtsc_ende,
rdtsc_unmittelbar,
rdtsc_wiederholend,
rdtsc_wiederholend_zinsfaktor,
rdtsc_aufrufend: int64;

function rdtsc: int64;
{
Taktzàhler für x86
http://en.wikipedia.org/wiki/Time_Stamp_Counter
}
begin
asm
rdtsc
end;
end;

procedure eingabe;
begin
// Noch offen Bereich der Eingabe prüfen.
write('Anfangskapital = '); readln(Geld);
write('Zinsfuß in % = ' ); readln(Zinsfusz);
write('Anzahl der Zinsen von von 0 bis 255 = '); readln(Zinsanzahl);
end;

function endkapital
(const Kapital: currency;
const prozent: single;
const Anzahl: byte
): Currency;
begin
endkapital := Kapital * intpower(1 + prozent / 100, Anzahl);
end;

function endkapital_iterativ
(const Kapital: currency;
const prozent: single;
const Anzahl: byte
): Currency;
var
i: byte;
Kapital_Anzahl,
Kapital_Anzahl_minus_1: currency;
begin
Kapital_Anzahl := Kapital;
Kapital_Anzahl_minus_1 := Kapital;
for i := Anzahl downto 1 do
begin
Kapital_Anzahl := Kapital_Anzahl_minus_1 * (1 + prozent / 100);
Kapital_Anzahl_minus_1 := Kapital_Anzahl;
end;
endkapital_iterativ := Kapital_Anzahl;
end;

function endkapital_iterativ_zinsfaktor
(const Kapital: currency;
const Prozent: single;
const Anzahl: byte
): Currency;
var
i: byte;
Zinsfaktor: extended;
begin
Zinsfaktor := 1;
for i := Anzahl downto 1 do
Zinsfaktor := Zinsfaktor * (1 + prozent / 100);
endkapital_iterativ_zinsfaktor := Kapital * Zinsfaktor;
end;

function endkapital_rekursiv
(const Kapital: currency;
const prozent: single;
const Anzahl: byte
): Currency;
begin
endkapital_rekursiv := Kapital; //Anfangswert
if Anzahl <> 0 then //Abbruchbedingung
endkapital_rekursiv :=
endkapital_rekursiv(Kapital, prozent, Anzahl - 1) *
(1 + prozent / 100);
end;

(*¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡*)
function endkapital_funktion_als_parameter
(const Kapital: currency;
Zinsfaktor: Typ_Funktion_Zinsfaktor
): Currency;

begin
endkapital_funktion_als_parameter :=
Kapital * Zinsfaktor(Zinsfusz, Zinsanzahl);
end;
(*¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡*)

(*¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿
function endkapital_direkt_funktion_als_parameter
(const Kapital: currency;
function Zinsfaktor
(prozent: single;
Anzahl: byte
): extended
): Currency;
begin
Zinsfaktor := intpower(1 + prozent / 100, Anzahl);
endkapital_direkt_funktion_als_parameter := Kapital * Zinsfaktor
end;
???????????????????????????????????????????????????????????????????*)
function Zinsfaktor_direkt
(prozent: single;
Anzahl: byte
): extended;
begin
Zinsfaktor_direkt := intpower(1 + prozent / 100, Anzahl);
end;

(*¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿
function endkapital_iterativ_funktion_als_parameter
(const Kapital: currency;
function Zinsfaktor
(prozent: single;
Anzahl: byte
): extended
): Currency;
var
i: byte;
Faktor: Extended;
begin
Faktor:=1;
for i:= Anzahl downto 1 do
Faktor := Faktor * (1 + Prozent / 100);
Zinsfaktor := Faktor;
endkapital_iterativ_funktion_als_parameter := Kapital * Zinsfaktor;
end;
???????????????????????????????????????????????????????????????????*)
function Zinsfaktor_iterativ
(prozent: single;
Anzahl: byte
): extended;
var
i: byte;
Faktor: Extended;
begin
Faktor:=1;
for i:= Anzahl downto 1 do
Faktor := Faktor * (1 + Prozent / 100);
Zinsfaktor_iterativ := Faktor;
end;

(*¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿
function endkapital_rekusiv_funktion_als_parameter
(const Kapital: currency;
function Zinsfaktor
(prozent: single;
Anzahl: byte
): Extended
): Currency;
begin
Zinsfaktor := 1;
if Anzahl <> 0 then
Zinsfaktor := Zinsfaktor(prozent, Anzahl-1) * ( 1 + prozent / 100);
endkapital_iterativ_funktion_als_parameter := Kapital * Zinsfaktor;
end;
???????????????????????????????????????????????????????????????????*)
function Zinsfaktor_rekursiv
(prozent: single;
Anzahl: byte
): extended;
begin
Zinsfaktor_rekursiv := 1;
if Anzahl <> 0 then
Zinsfaktor_rekursiv :=
Zinsfaktor_rekursiv(prozent, Anzahl-1) *
(1 + prozent / 100);
end;

begin
writeln;
eingabe;
write('-');
writeln('-');
writeln('1. In einem ausgerechnet.');
writeln(' Geld[Zinsanzahl] := Geld[0] * ( 1 + Zinsfuß / 100) ^
Zinsanzahl');
rdtsc_anfang := rdtsc;

writeln(endkapital(Geld, Zinsfusz, Zinsanzahl):20:4);

rdtsc_ende := rdtsc;
rdtsc_unmittelbar := rdtsc_ende - rdtsc_anfang;
write('-');
writeln('-');
writeln('2.a Als iterative Schleife mit "for downto do" gerechnet.');
writeln(' Von Zinsanzahl = ', Zinsanzahl, ' hinunter bis 1.');
write(' Geld := Geld * (1 + Zinsfuß / 100)');
writeln(' wiederholte sich ', Zinsanzahl, ' mal.');
rdtsc_anfang := rdtsc;

writeln(endkapital_iterativ(Geld, Zinsfusz, Zinsanzahl):20:4);

rdtsc_ende:= rdtsc;
rdtsc_wiederholend := rdtsc_ende - rdtsc_anfang;
write('-');
writeln('-');
writeln('2.b Als iterative Schleife mit "for downto do" gerechnet.');
writeln(' Von Zinsanzahl = ', Zinsanzahl, ' hinunter bis 1.');
write(' Zinsfaktor := Zinsfaktor * (1 + Zinsfuß / 100)');
writeln(' wiederholte sich ', Zinsanzahl, ' mal.');
writeln(' Geld[Zinsanzahl] := Geld[0] * Zinsfaktor');
rdtsc_anfang := rdtsc;

writeln(endkapital_iterativ_zinsfaktor(Geld, Zinsfusz,
Zinsanzahl):20:4);

rdtsc_ende:= rdtsc;
rdtsc_wiederholend_zinsfaktor := rdtsc_ende - rdtsc_anfang;
write('-');
writeln('-');
writeln('3. Als rekursive Funktion geschrieben.');
writeln(' Von Zinsanzahl = ', Zinsanzahl, ' hinunter bis 1.');
write(' Geld[Zinsanzahl]:=Geld[Zinsanzahl-1]*(1+Zinsfuß/100)');
writeln(' rief sich ', Zinsanzahl, ' mal auf.');
rdtsc_anfang := rdtsc;

writeln(endkapital_rekursiv(Geld, Zinsfusz, Zinsanzahl):20:4);

rdtsc_ende := rdtsc;
rdtsc_aufrufend := rdtsc_ende - rdtsc_anfang;
write('-');
writeln('-');
//Takte der Pozeduren, Funktionen als Laufzeiteinheit.
writeln('Ermittelte Takte:');
write(' ', rdtsc_unmittelbar);
writeln(' Takte braucht die unmittelbare Funktion.');
write(' ', rdtsc_wiederholend);
writeln(' Takte braucht die sich wiederholende Lösung.');
write(' ', rdtsc_wiederholend_zinsfaktor);
writeln(' Takte braucht die sich wiederholende Lösung mit Zinsfaktor.'
);
write(' ', rdtsc_aufrufend);
writeln(' Takte braucht die sich aufrufende Funktion.');
writeln;
write('=');
writeln('=');
write('=');
writeln('=');
writeln;
rdtsc_anfang := rdtsc;

write(endkapital_funktion_als_parameter(Geld, @Zinsfaktor_direkt):20:4);

rdtsc_ende := rdtsc;
rdtsc_unmittelbar := rdtsc_ende - rdtsc_anfang;
writeln(' Endkapital ermittelt mit direkter Funktion als Parameter.');
rdtsc_anfang := rdtsc;

write(endkapital_funktion_als_parameter(Geld,
@Zinsfaktor_iterativ):20:4);

rdtsc_ende:= rdtsc;
rdtsc_wiederholend := rdtsc_ende - rdtsc_anfang;
writeln(' Endkapital ermittelt mit iteraiver Funktion als Parameter.');
rdtsc_anfang := rdtsc;

write(endkapital_funktion_als_parameter(Geld,
@Zinsfaktor_rekursiv):20:4);

rdtsc_ende:= rdtsc;
rdtsc_aufrufend := rdtsc_ende - rdtsc_anfang;
writeln(' Endkapital ermittlet mit rekursiver Funktion als Parameter.');
write('-');
writeln('-');
//Takte der Pozeduren, Funktionen als Laufzeiteinheit.
write('Ermittelte Takte für alle Funktionen');
writeln(' die eine Funktion als Parameter haben.');
write(' ', rdtsc_unmittelbar);
writeln(' Takte braucht die direkte Funktion.');
write(' ', rdtsc_wiederholend);
writeln(' Takte braucnt die iterative Funktion.');
write(' ', rdtsc_aufrufend);
writeln( ' Takte braucht die rekursive Funktion.');
write('-');
writeln('-');
writeln;
end.

#v-



ln -s /dev/cerebro /dev/null is full
Was ich denke ist leer und es quillt über.
Pseudonym...count.zero@interrupt; verarbeiten, lernen endet bei Null.
 

Lesen sie die antworten

#1 Sieghard Schicktanz
07/04/2009 - 01:52 | Warnen spam
Hallo count,

Du schriebst am Mon, 06 Apr 2009 21:14:21 +0200:

Ich verwende den free pascal Kompilierer.



Da sagtr man auch im Deutschen "Compiler" - der Anglizismus hat sich
durchgesetzt.

Free Pascal Compiler version 2.2.2 [2008/10/26] for i386



Alte Version - aktuell ist 2.2.5

Sind in den Beriechen mit (*¿¿¿¿¿.?????*)



Äh, was riecht da?

die Funktionen die eine Funktion_als_Parameter
haben für Standard Pascal richtig?



BTW, hast Du das Programm denn schon mal laufen lassen und Dir die
Ergebnisse angeschaut, ob die auch Deinen Erwartungen entsprechen?
Ich möchte mit einiger Sicherheit annehmen, daß Du das _nicht_ getan hast.
Für das erfolgreiche Entwickeln von Software ist es _unumgànglich_, daß der
Programmierer nicht nur syntaktisch korrekte Programme schreiben kann (was
anderes nimmt ihm der Compiler auch gar nicht ab), sondern daß er auch
_versteht_, _was_ diese tun.

Das kann zur Zeit der verwendte fpc noch nicht!



Das kann kein Compiler. ;-)
Äh, sorry, Du bezogst Dich ja auf Deine obige Frage... ;-)
_Doch_, kann er _schon_.
Aber: der FPC ist ein Multi-Mode-Compiler, und deshalb kommt es auf den
aktuell eingestellten Mode an, (ob und) _wie_ er bestimmte Konstrukte
angegeben haben will.

In den Bereichen mit (*¡!¡!¡.!¡!¡!*) und nachfolgend
ist/sind Funktion(en) mit Funktion(en)_als_Parameter
diese habe ich versucht nachzubilden.

(*¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡*)
type
Typ_Funktion_Zinsfaktor =
function
(prozent: single;
Anzahl: byte
): extended;


^ Naja.
(*¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡*)



[noise silenced]

(*¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡!¡*)
function endkapital_funktion_als_parameter
(const Kapital: currency;
Zinsfaktor: Typ_Funktion_Zinsfaktor
): Currency;



Ok, das ist die von FPC benutzte Syntax.

(*¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿
function endkapital_direkt_funktion_als_parameter
(const Kapital: currency;
function Zinsfaktor
(prozent: single;
Anzahl: byte
): extended
): Currency;



Ne, so geht's bei FPC nicht. Das wàre die "klassische" Syntax von
Wirth-Pascal. (Leider nur AFAIK, ich hab' grad nix zum Nachschauen zur
Hand.)

write('=');



BTW, weil obige Konstruktion bei Dir so hàufig vorkommt:
Mal an eine Prozedur gedacht, die sowas algorithmisch erzeugt? D.h. mit
Angabe des Zeichens und der Anzahl Wiederholungen, so daß der Programmtext
nicht von so vielen informationsfreien Zeichenstreifen zerschnitten wird?
Natürlich ginge auch eine Funktion, die einen solchen String zurückliefert,
der dann als Parameter an ein Write(Ln) verfüttert werden kann - sowas
gibt's übrigens beim FPC schon fertig.

write(endkapital_funktion_als_parameter(Geld, @Zinsfaktor_direkt):20:4);


^
Hier gilt wieder, den Compiler-Mode im Auge zu haben - nicht in _jedem_
Mode ist der Adressoperator nötig, in einigen ist er nicht einmal zulàssig.
Gut, daß Du den Mode am Programmanfang jetzt festgelegt hast...

BTW, die Algorithmen der einzelnen Funktionen habe ich mir jetzt nicht
nàher angeschaut - aufgrund der Ergebnisse und der Laufzeiten könnte ich
mir aber vorstellen, daß da noch ein paar Inkonsistenzen versteckt sind.
Die zu suchen ist mir das Programm aber zu unübersichtlich.

Außerdem solltest Du mal überlegen, was Du bei Deiner "Laufzeitbestimmung"
überhaupt misst, d.h. ob das wirklich die Laufzeit Deiner Funktionen allein
ist oder ob da noch unerwünschte weitere Anteile hineinspielen. Ich könnte
mir vorstellen, daß letzteres da teilweise recht kràftig mitspielt...

So, weiteres gibt's aber erst nach einem Nachweis, daß Du das Programm auch
wirklich mal ausprobiert hast.

(Weitergabe von Adressdaten, Telefonnummern u.à. ohne Zustimmung
nicht gestattet, ebenso Zusendung von Werbung oder àhnlichem)
Mit freundlichen Grüßen, S. Schicktanz

Ähnliche fragen