Autor Beitrag
regsnerven
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 28.05.09 21:42 
Hallo Leute,

Darlehenstilgung bei Zinssatz X in Y Jahren, das soll das Programm machen.

Ich habe ein Programm geschrieben, bei dem man den Kredit eingeben soll, dann noch den Prozentsatz und die Jahre, in denen der Kredit getilgt werden soll.

Jetzt habe ich auch einen Code geschrieben, der eigentlich funktionieren sollte, aber das Teil spinnt iwie. Ich weiß aber nicht warum.

Ich habe zur Kontrolle eine Art Ausgabefunktion geschrieben, die nach jedem Durchlauf der Schleife die Werte ausgibt.
Seht ihr alles auf den Screenshots ;)
Dabei kam dann raus, dass das Teil einfach nicht den Wert auf 3,5527136788005E-14 oder so setzt. Aber schauts euch selber an.
Eigentlich sollte er nachdem die Annuität 2000 erreicht hat, abbrechen. Das zeigt das rechte Programm, das anhand von Kredit, Zinssatz und Annuität in einem Stinggrid ausgibt, wie das über die Jahre abläuft.

Der Code des ersten Programms habe ich auch angehängt.
Ich hoffe, ihr habt da mal ne Idee zu.

Moderiert von user profile iconNarses: Bild als Anhang hochgeladen.
Danke für's hochladen. Dachte, es ginge nur eine Datei.

Achja. Was ich noch sagen wollte. Ich habe mal für die 500, die am Ende dazu addiert werden, 499 eingesetzt und das funktioniert. Warum check ich auch nicht.


Gr33tZ
Rn
Einloggen, um Attachments anzusehen!


Zuletzt bearbeitet von regsnerven am Fr 29.05.09 14:52, insgesamt 1-mal bearbeitet
regsnerven
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 29.05.09 14:51 
Okay, hier noch mal die genaue Zahl. Ich check das echt nicht. Warum macht Delphi son Schrott?

3,5527136788005E-14

Wenn ich die allerdings in der IF-Abfrage angebe, dann wird das Teil zur Endlosschleife. ~.~
baka0815
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 489
Erhaltene Danke: 14

Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
BeitragVerfasst: Fr 29.05.09 15:03 
3,5527136788005E-14 entsprechen ja 0,0000000000000035527...

Klingt für mich nach 'nem Fließkommaproblem. Nimmst du die Datentypen Real, Extended oder Double? Wenn ja, versuch mal Currency.
regsnerven
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 29.05.09 15:11 
Ich benutze real.
Lol ^^ Du bist ein Gott. DAnke. Hat funktioniert.

Aber warum? Ich meine, warum ist 0 nicht gleich 0, sondern diese komische Zahl da, wenn ich REAL und nicht CURRENCY nehme?
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Fr 29.05.09 15:33 
Hast du der Real-Variable wirklich 0 zugewiesen? Dann finde ich das etwas seltsam, kenne mich aber mit Fließkommazahlen in Delphi zu wenig aus, um da richtig Stellung zu nehmen. Tatsächlich musst du immer runden, um einen halbwegs verwendbaren Wert haben willst, denn Single, Double, Extendet und natürlich Real werden intern binär und in wissenschaftlicher Darstellung gespeichert, und diese Kombination hat so ziemlich überhaupt nichts mit dem Dezimalsystem zu tun. Folglich ist das Ganze auch nicht genau.

Curency hingegen ist einfach ein Integer, der aber immer durch IMHO 100 geteilt wird. 123,45 (Euro) wird also intern als "12345 / 100" dargestellt, und das ist eben wieder genau. Für Währungen und dergleichen also immer Currency verwenden :idea:
nagel
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 708

Win7, Ubuntu 10.10

BeitragVerfasst: Sa 30.05.09 23:45 
user profile iconYogu hat folgendes geschrieben Zum zitierten Posting springen:
... der aber immer durch IMHO 100 geteilt wird.

Durch 10000.
arj
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 378

Win XP/Vista, Debian, (K)Ubuntu
Delphi 5 Prof, Delphi 7 Prof, C# (#Develop, VS 2005), Java (Eclipse), C++, QT, PHP, Python
BeitragVerfasst: So 31.05.09 10:29 
Üblicherweise macht man Fließkommazahlenvergleiche wegen der Ungenauigkeit immer mit nem Epsilon.

Sei Epsilon > 0, dann gibt Epsilon (im Code einfach als Variable e), die benötigte Genauigkeit an
und ein Vergleich schaut dann so aus:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
var epsilon : Single;

epsilon := 0.0000001;
// entspricht if zahl1 = zahl2 then
if (zahl1 >= zahl2 - epsilon) and (zahl1 <= zahl2 + epsilon) then
begin
end;


Allerdings kann es natürlich sein, dass der Wert den Du dem epsilon gibst - im Code 0.0000001 - von
einer Fließkommazahl wiederrum nicht exakt dargestellt werden kann, deshalb musst Du da ggf. bisschen probieren.

Der Vergleich kann dann also in ne Funktion gepackt werden:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
function Equals(f1, f2 : Single) : Boolean;
const epsilon : Single = 0.0000001;
begin
// entspricht if f1 = f2 then
Result := (f1 >= f2 - epsilon) and (f1 <= f2 + epsilon);
end;


Dann sollte die Nullprüfung auch funkltionieren.
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: So 31.05.09 10:34 
Oder, unter Verwendung der Unit Math:
ausblenden Delphi-Quelltext
1:
2:
3:
uses ..., Math, ...;
if IsZero(FloatValue) then foo;
if SameValue(FloatValue, 42then bar;

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."


Zuletzt bearbeitet von Martok am So 31.05.09 10:39, insgesamt 1-mal bearbeitet
arj
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 378

Win XP/Vista, Debian, (K)Ubuntu
Delphi 5 Prof, Delphi 7 Prof, C# (#Develop, VS 2005), Java (Eclipse), C++, QT, PHP, Python
BeitragVerfasst: So 31.05.09 10:38 
Mist, das dachte ich mir fast dass es da schon was gibt *g*
regsnerven
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: So 07.06.09 15:30 
Also jetzt funktioniert es wie gesagt, aber ist ungenau. Check ich aber iwie nicht. Also ne Ungenauigkeit von rund 50 oder so. Das ist doch nen bisschen hart.

Was ich aber nicht verstehe ist, warum man runden muss, wenn man bei ner REAL 0 erhalten will. Das ist doch iwie unlogisch.
Robert.Wachtel
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 895
Erhaltene Danke: 7

Windows 7 Ultimate x64
D5 Ent, D7 Arch, RAD Studio 2010 Pro, VS 2008
BeitragVerfasst: So 07.06.09 15:41 
user profile iconregsnerven hat folgendes geschrieben Zum zitierten Posting springen:
[...] Was ich aber nicht verstehe ist, warum man runden muss, wenn man bei ner REAL 0 erhalten will. Das ist doch iwie unlogisch.

de.wikipedia.org/wiki/Gleitkommazahl
jfheins
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: So 07.06.09 15:49 
Nein, ist es nicht wenn man es versteht ;)

Da dein Computer leider nicht unendlich viel speicher hat, muss er die (unendlich genaue) Zahl annähern. Resultat: Er kann die Zahl nur auf (bspw.) 5 Stellen genau speichern. (5 zur Anschaulichkeit, in der Realität 10-15 Stellen)

D.h.: a := 1000000; // wird als 1,0000 * 10^6 gespeichert
Wenn du jetzt eine 1 dazuaddiert entsteht folgendes "Paradoxon":

1,0000 * 10^6 + 1,0000 * 10^0 = (Exponenten angleichen) = 1,0000 * 10^6 + 0,000001 * 10^6 = 1,000001 * 10^6 = (Da nur 5 signifikante Stellen) = 1,0000 * 10^6

Also eine Million plus 1 ist immernoch eine Million.

Macht dein Taschenrechner übrigens auch. Tipp mal 1E20 + 1 - 1E20 ein ;)
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: So 07.06.09 22:23 
Hinzukommt, dass man Zahlen in Dezimaldarstellung nicht genau in ihrer Binärdarstellung repräsentieren kann: www.michael-puff.de/...el/Fliesskomma.shtml
regsnerven
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 08.06.09 19:56 
Danke jfheins ^^ Das ist doch mal etwas, was man verstehen kann.

Danke natürlich auch allen anderen für die Hilfe und die Links :D

Ich beende den Thread hiermit mal.

Gr33tZ
Rn