AGB  ·  Datenschutz  ·  Impressum  







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

Problem mit RoundTo((100*0.01),0)

Ein Thema von zecke · begonnen am 18. Apr 2008 · letzter Beitrag vom 23. Apr 2008
Antwort Antwort
Seite 1 von 3  1 23      
Benutzerbild von zecke
zecke

Registriert seit: 17. Jan 2004
494 Beiträge
 
Turbo Delphi für Win32
 
#1

Problem mit RoundTo((100*0.01),0)

  Alt 18. Apr 2008, 01:15


Nach sehr langer Zeit habe ich mal wieder ein Problem. Mir fällt einfach kein Fehler auf.

Ich möchte Zahlen im Grunde einfach immer abrunden (ohne Nachkommastellen). Das mache ich mit RoundTo und RoundMode habe ich auf truncate.

Erstmal der Code:

Delphi-Quellcode:
   p7:=RoundTo((staedte*0.01),0);
   showmessage(floattostr(staedte));
   showmessage(floattostr(RoundTo((100*0.01),0)));
   showmessage(floattostr(p7));
staedte ist vom Typ Real, ebenso wie p7. Außerdem hat staedte den Wert 100.

showmessage Nummer 1 zeigt mir korrekter Weise "100" an. showmessage Nummer 2 zeigt mir korrekter Weise "1" an. showmessage Nummer 3 zeigt mir "0" an. (Die 5000 showmessage Befehle sind übrigens nur zu Demonstrationszwecken vorhanden )

Was mache ich denn hier falsch? In der Hilfe habe ich bereits geforscht, auch die Forensuche half mir nicht weiter. Hoffe ich habe keinen Thread übersehen und ihr könnt mir einen Tipp geben. Habe übrigens auch schon die anderen RoundModes ausprobiert, lediglich Up macht es richtig, logisch, aber das will ich ja nicht, falls staedte eine andere Zahl ist.
mfg zecke
  Mit Zitat antworten Zitat
Benutzerbild von peschai
peschai

Registriert seit: 15. Feb 2004
Ort: Göppingen
270 Beiträge
 
Delphi XE5 Professional
 
#2

Re: Problem mit RoundTo((100*0.01),0)

  Alt 18. Apr 2008, 05:36
Hallo
Also ich bin verblüfft! Ich kann das Problem unter Delphi2007Prof nachstellen!
-> Das zweite Showmessage zeigt ein anderes Ergebnis, was nicht sein darf!
Zuerst dachte ich, daß dies ein Problem von REAL sei, aber selbst die Umstellung auf DOUBLE zeigt hier unterschiedliche Werte an!
Delphi-Quellcode:
procedure TForm1.Button4Click(Sender: TObject);
var
  p7 : double;
  staedte : double;
begin
  p7 := 0.0;
  staedte := 100.0;

  SetRoundMode(rmTruncate);

  p7:=RoundTo((100.0*0.01),0); showmessage(floattostr(p7));
  p7:=RoundTo((Staedte*0.01),0); showmessage(floattostr(p7)); // hier anderes ergebnis!
end;
Peter Schaible
  Mit Zitat antworten Zitat
Benutzerbild von peschai
peschai

Registriert seit: 15. Feb 2004
Ort: Göppingen
270 Beiträge
 
Delphi XE5 Professional
 
#3

Re: Problem mit RoundTo((100*0.01),0)

  Alt 18. Apr 2008, 05:45
Hallo
Noch ein Ergänzung:
Ein Änderung des Potenzparameters von "0" auf "-1" bringt ebensfalls unterschiedliche Ergebnisse "1" und "0,9"!
Delphi-Quellcode:
  // Staedte, p7 : double; // RoundTo(Double,...)
  SetRoundMode(rmTruncate);
  Staedte := 100.0;
  p7:=RoundTo((100.0*0.01),-1); showmessage(floattostr(p7));
  p7:=RoundTo((Staedte*0.01),-1); showmessage(floattostr(p7));
War so frei und habe bei CodeGear einen BugReport eröffnet, nachdem ich dort in der IssueSuche nichts mit RoundTo gefunden habe.
Zitat:
Report From: Delphi-BCB/Compiler/Delphi Report #: 61093
Peter Schaible
  Mit Zitat antworten Zitat
Benutzerbild von peschai
peschai

Registriert seit: 15. Feb 2004
Ort: Göppingen
270 Beiträge
 
Delphi XE5 Professional
 
#4

Re: Problem mit RoundTo((100*0.01),0)

  Alt 18. Apr 2008, 06:25
Hallo,
Dieser Delphi Fehler hat mir keine Ruhe gelassen, aber hier ein ein Workaround:
Habe die original Funktion aus "math" mit extended redefiniert und damit scheint es jetzt zu funktionieren...
Delphi-Quellcode:
function MyRoundTo(const AValue: Extended; const ADigit: TRoundToRange): Extended;
var
  LFactor: Extended;
begin
  LFactor := IntPower(10, ADigit);
  Result := Round(AValue / LFactor) * LFactor;
end;
Das Problem scheint zu sein, daß math.RoundTo mit Double definiert ist, intern aber das System.Round verwendet wird, was aber mit Extended definiert ist. Delphi scheint hier ein Problem zu haben mit der Übergabe der "intern konvertierten werte" an die Round funktion ....
Peter Schaible
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

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

Re: Problem mit RoundTo((100*0.01),0)

  Alt 18. Apr 2008, 06:35
Komsich, das dieser Fehler vorher noch niemand aufgefallen zu sein scheint.
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von peschai
peschai

Registriert seit: 15. Feb 2004
Ort: Göppingen
270 Beiträge
 
Delphi XE5 Professional
 
#6

Re: Problem mit RoundTo((100*0.01),0)

  Alt 18. Apr 2008, 07:08
@mkienzler
du hast recht, das hat mich auch gewundert. Könnte aber daran liegen daß "SetRoundMode(rmTruncate);" wohl eher selten benutzt wird. Mit der standard Einstellung scheint das problem nicht sichtbar zun werden...

Ich sehe hier ein großes Risiko, daß eventuell alle Funktionen mit Double die intern eine Extended-Funktion aufrufen damit in besonderen fällen (selten?) betroffen sein könnten... Am Liebsten sollten alle diese mit extended redefiniert werden ....
Peter Schaible
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

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

Re: Problem mit RoundTo((100*0.01),0)

  Alt 18. Apr 2008, 07:20
Ich verwende eigentlich fast immer Extended, das werden viele andere vielleicht auch machen.
Markus Kinzler
  Mit Zitat antworten Zitat
DelphiKlaus

Registriert seit: 18. Okt 2006
100 Beiträge
 
Delphi 6 Professional
 
#8

Re: Problem mit RoundTo((100*0.01),0)

  Alt 18. Apr 2008, 07:32
Hallo,

liegt das nicht vielleicht einfach daran, dass z.B. 100 * 0.01 nicht unbedingt 1 ergibt, sondern vielleicht 0.99999999.
  Mit Zitat antworten Zitat
angos

Registriert seit: 26. Mai 2004
Ort: Rheine
549 Beiträge
 
Delphi 11 Alexandria
 
#9

Re: Problem mit RoundTo((100*0.01),0)

  Alt 18. Apr 2008, 07:35
das problem wird eher sein, dass wenn man einer Real-Variable den Wert 100 zuweist, diese einen tatsächlichen Wert von 99,9999999999999999 hat da es ja nicht auftritt, wenn die gesamte berechnung direkt durchgeführt wird.
aber ansich habe ich die gleiche Vermutung wie du... das ist halt einfach der Grund, Fließkommazahlen zu vermeiden wunderbar dargestellt an einem praktischen Beispiel

Gruß
Ansgar
  Mit Zitat antworten Zitat
Benutzerbild von peschai
peschai

Registriert seit: 15. Feb 2004
Ort: Göppingen
270 Beiträge
 
Delphi XE5 Professional
 
#10

Re: Problem mit RoundTo((100*0.01),0)

  Alt 18. Apr 2008, 09:13
@DelphiKlaus&Angos
Natürlich habt ihr hier recht, das digitale Speichern von Gleitkommazahlen hat dieses Problem grundsätzlich.
Das Verhalten hier ist aber, daß trotz identischen Typen (alles Double) hier ein unterscheidliches Verhalten/Ergebnis auftritt.
Ich hätte weniger ein Problem wenn dieser DigitaleFehler identisch aufgetreten wäre.
Codegear muss hier ein identisches Verhalten sicherstellen!
Delphi-Quellcode:
// Staedte, p7 : double; // RoundTo(Double,...)
SetRoundMode(rmTruncate);
Staedte := 100.0;
p7:=RoundTo((100.0*0.01),-1); showmessage(floattostr(p7));
p7:=RoundTo((Staedte*0.01),-1); showmessage(floattostr(p7));
Peter Schaible
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


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 04:45 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