AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Runden liefert falsches Ergebnis

Ein Thema von alleinherrscher · begonnen am 18. Dez 2009 · letzter Beitrag vom 18. Dez 2009
Antwort Antwort
Benutzerbild von alleinherrscher
alleinherrscher

Registriert seit: 8. Jul 2004
Ort: Aachen
797 Beiträge
 
Delphi XE2 Professional
 
#1

Runden liefert falsches Ergebnis

  Alt 18. Dez 2009, 14:30
Hi@all!

Ich habe mir mal den spass gemacht und eine eigene Rundungsfunktion geschrieben. Es geht hier um das Prinzip, ich möchte also verstehen, warum ich falsche Ergebnisse bekomme und nicht hören, dass Delphi ja eine interne Rundungsfunktion hat :

Delphi-Quellcode:

function roundexact(X:extended;digits:integer):extended;
var intzahl:integer;
    intzahl2:integer;
begin

 intzahl:=trunc(x*power(10,digits+1));
 intzahl2:=trunc(x*power(10,digits))*10;

 if intzahl-intzahl2 < 5 then
  result:=intzahl2/power(10,digits+1)
 else
  result:=int(intzahl2/10+1)/power(10,digits);


end;
Zum Fehler:

An und für sich funktioniert diese Funktion super. Ich glaube auch nicht, dass der Fehler direkt an dem Funktionsaufbau liegt, sondern daran, wie Delphi intern Single zu Extended etc konvertiert:

Ich habe folgende Berechnung, die am Schluss gerundet werden soll:

Code:
3675*(14/200+0.009)
Das Ergebnis ist, wie jeder noch leicht selber ausrechnen können sollte: 290.325

Demzufolge müsste unsere Rundungsfunktion als Ergebnis 290.33 liefern, richtig?

Dies tut sie auch, wenn ich sie mit folgendem Befehl starte:

showmessage(floattostr(roundexact(290.325,2))); //Messagebox zeigt wie erwartet 290.33 an Wenn ich aber schreibe:

showmessage(floattostr(roundexact(3675*(14/200+0.009),2))); //Messagebox zeigt 290.32 an ?!?! erhalte ich als ergebnis 290.32

Kann mir das jemand erklären??

Ich habe mal ein bisschen mit dem Debugger rumgespielt:

Wenn das Ergebnis falsch berechnet wird, liefert

intzahl:=trunc(x*power(10,digits+1)); das Ergebnis 290324 anstatt von 290325

WARUM???


Viele Grüße,
Michael

[edit] Mit X als Single-precision funktionierts! Warum? Ist da ein Delphi-interner Fehler bei der Umwandlung von Single->Extended oder hat das generell irgendwas mit der Darstellbarkeit von Zahlen in Computer zu tun? -> Schätze Delphi wandelt das Ergebnis bei der Parameterübergabe in 290.324999999999999999 um oder so?[/edit]

[edit2] Dafür gehts dann mit anderen Zahlen nicht mehr...z.B. 4650*0.0995=462.675 ... woran liegt das??? [/edit2]
„Software wird schneller langsamer als Hardware schneller wird. “ (Niklaus Wirth, 1995)

Mein Netzwerktool: Lan.FS
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.477 Beiträge
 
Delphi 12 Athens
 
#2

Re: Runden liefert falsches Ergebnis

  Alt 18. Dez 2009, 16:21
Gebrochene Fließkommazahlen lassen sich mit verschiedenen Exponenten darstellen.
Je nach vorherigen Operationen und Exponent treten Ungenauigkeiten auf.

Statt 290,325 kann die Variable intern auch z.B. 290,324999999998 enthalten.
Bei der Umwandlung in einen String wird das natürlich ausgeglichen und die Anzeige stimmt.
Ein direkter Vergleich würde aber Ungleichheit feststellen.

Trunc(2903224,999999998) ergibt 2903224.
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.861 Beiträge
 
Delphi 11 Alexandria
 
#3

Re: Runden liefert falsches Ergebnis

  Alt 18. Dez 2009, 16:23
Zitat:
Gebrochene Fließkommazahlen lassen sich mit verschiedenen Exponenten darstellen.
Wobei normalerweise Basis 16 verwendet wird
Markus Kinzler
  Mit Zitat antworten Zitat
hugo1990

Registriert seit: 27. Dez 2006
166 Beiträge
 
Turbo Delphi für Win32
 
#4

Re: Runden liefert falsches Ergebnis

  Alt 18. Dez 2009, 16:38
Zitat von mkinzler:
Wobei normalerweise Basis 16 verwendet wird
Warum 16, laut IEEE 754 sollte doch die Basis 2 für Gleitkommazahlen verwendet werden oder macht das Delphi anders?
Ich meine im Endeffekt kommt es auf's Selbe raus, weil 16 ja auch eine 2er Potenz ist, aber es geht mir jetzt eher ums Prinzip.
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.477 Beiträge
 
Delphi 12 Athens
 
#5

Re: Runden liefert falsches Ergebnis

  Alt 18. Dez 2009, 17:58
Eine Sache zu verstehen ist eine Sache, für andere verständlich zu formulieren schon schwieriger...

Schau mal Wiki Gleitkommazahl unter Dezimalzahlen.
  Mit Zitat antworten Zitat
Benutzerbild von alleinherrscher
alleinherrscher

Registriert seit: 8. Jul 2004
Ort: Aachen
797 Beiträge
 
Delphi XE2 Professional
 
#6

Re: Runden liefert falsches Ergebnis

  Alt 18. Dez 2009, 18:02
Und was kann ich dagegen tun? Weiß jemand, wie die Umwandlung in nen String dieses Problem "umgeht" und dort exakt anzeigt?
„Software wird schneller langsamer als Hardware schneller wird. “ (Niklaus Wirth, 1995)

Mein Netzwerktool: Lan.FS
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#7

Re: Runden liefert falsches Ergebnis

  Alt 18. Dez 2009, 19:32
Berücksichtige die Schutzstellen, addiere also vor dem "Trunc" 0.5 dazu.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von alleinherrscher
alleinherrscher

Registriert seit: 8. Jul 2004
Ort: Aachen
797 Beiträge
 
Delphi XE2 Professional
 
#8

Re: Runden liefert falsches Ergebnis

  Alt 18. Dez 2009, 19:44
Okay, ich habs jetzt umgebaut zu:

Delphi-Quellcode:
function roundexact(X:single;digits:integer):single;
begin

 result:=x*power(10,digits)+0.5;
 result:=trunc(result);
 result:=result/power(10,digits);

end;
Müsste ich aber nicht eigentlich 0.50001 dazuaddieren oder sowas?
„Software wird schneller langsamer als Hardware schneller wird. “ (Niklaus Wirth, 1995)

Mein Netzwerktool: Lan.FS
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:38 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz