| Autor |
Beitrag |
regsnerven
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: 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 Narses: 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
|
Verfasst: 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
      
Beiträge: 489
Erhaltene Danke: 14
Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
|
Verfasst: 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
|
Verfasst: 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
      
Beiträge: 2598
Erhaltene Danke: 156
Ubuntu 13.04, Win 7
C# (VS 2013)
|
Verfasst: 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 
|
|
nagel
      
Beiträge: 708
Win7, Ubuntu 10.10
|
Verfasst: Sa 30.05.09 23:45
Yogu hat folgendes geschrieben : | | ... der aber immer durch IMHO 100 geteilt wird. |
Durch 10000.
|
|
arj
      
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
|
Verfasst: 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:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| var epsilon : Single;
epsilon := 0.0000001; 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:
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| function Equals(f1, f2 : Single) : Boolean; const epsilon : Single = 0.0000001; begin Result := (f1 >= f2 - epsilon) and (f1 <= f2 + epsilon); end; |
Dann sollte die Nullprüfung auch funkltionieren.
|
|
Martok
      
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: So 31.05.09 10:34
Oder, unter Verwendung der Unit Math:
Delphi-Quelltext 1: 2: 3:
| uses ..., Math, ...; if IsZero(FloatValue) then foo; if SameValue(FloatValue, 42) then 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
      
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
|
Verfasst: 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
|
Verfasst: 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
      
Beiträge: 895
Erhaltene Danke: 7
Windows 7 Ultimate x64
D5 Ent, D7 Arch, RAD Studio 2010 Pro, VS 2008
|
Verfasst: So 07.06.09 15:41
regsnerven hat folgendes geschrieben : | | [...] 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
      
Beiträge: 918
Erhaltene Danke: 158
Win 10
VS 2013, VS2015
|
Verfasst: 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
|
Verfasst: 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
|
Verfasst: 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
Ich beende den Thread hiermit mal.
Gr33tZ
Rn
|
|
|