Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi trunc liefert nicht das erwartete Ergebnis (https://www.delphipraxis.net/149310-trunc-liefert-nicht-das-erwartete-ergebnis.html)

Daimonion 18. Mär 2010 15:17


trunc liefert nicht das erwartete Ergebnis
 
Hallo an alle

In meinem Programm berechne ich verschiedene Position auf die 2. Kommastelle genau. Um nicht in irgendwelche Rechenfehler zu rennen, multipliziere ich die Double Werte vorher mit 100 und wende dann darauf einen Trunc an. (siehe Beispiel)
Code:
rp := (trunc((dp*100)) + trunc((offset*100)))/100; //Real Position
Nun habe ich festgestellt, dass mir die Funktion Trunc die Werte falsch liefert.

Gemerkt habe ich das am Wert offset. Dieser war auf 0.61 . Mit 100 multipliziert ergibt dieser 61. Doch wenn ich darauf die Funktion Trunc anwende, dann gibt diese mir 60 zurück.


Wieso denn das? Und wie kann ich das umgehen?

Danke für die Infos.

Grüße
Thomas

DeddyH 18. Mär 2010 15:25

Re: trunc liefert nicht das erwartete Ergebnis
 
Wahrscheinlich war der Wert nicht genau 0.61, sondern 0.609999999 oder sowas.

blink182 18. Mär 2010 15:26

Re: trunc liefert nicht das erwartete Ergebnis
 
mhm komisch :-D
habs eben auch mal getestet und das selbe "Problem" gehabt.
Was ich mir vorstellen kann ist, dass die Zahl intern nicht genau dargestellt werden kann, kann ich aber nicht sagen. (Mantisse und Exponent)

Hab dann mal bisschen was getestet:
Delphi-Quellcode:
trunc(0.61*100) // -> 61
//
var offset:real;
offset:=0.61;
trunc(offset*100) //-> 60
//
var offset:double;
offset:=0.61;
trunc(offset*100) //-> 60
//
var offset:single;
offset:=0.61;
trunc(offset*100) //-> 61
//
var offset:extended;
offset:=0.61;
trunc(offset*100) //-> 61
//
var offset, temp: real;
offset=0.61;
temp:=offset*100;
trunc(temp) //->61

DeddyH 18. Mär 2010 15:28

Re: trunc liefert nicht das erwartete Ergebnis
 
Ließe sich das nicht mit math.(Simple)RoundTo umgehen? Ich hab das gerade nicht so genau im Kopf.

Daimonion 18. Mär 2010 15:54

Re: trunc liefert nicht das erwartete Ergebnis
 
Liste der Anhänge anzeigen (Anzahl: 1)
@DeddyH

Nein, denn beim Debuggen zeigt er mir auch wirklich die 0.61 an (self.dp war nämlich 0.005 und wurde richtig verarbeitet). Deine Funktion SimpleRoundTo oder ähnliches hab ich in Math bis jetzt leider nicht gefunden.

Edit:So MAth.simpleroundto gefunden aber nicht in meinem D5, sondern bei Embarcardero. ;)

An sich will ich ja auch nicht runden , sondern nach der 2. Kommastelle abschneiden.

@ blink182

Danke für den schnellen Test. Jetzt gilt es vielleicht nur noch festzustellen, warum trunc mit Double und Real nicht korrekt arbeitet.

@all

Kann denn jemand dieses Verhalten erklären?

Danke und Grüße
Daimonion

Edit:

Ich habe gerade nochmal einen Screenshot angehangen, wo auch die Werte vom Debugger drin stehen und ich mal eine temporäre Variable genutzt hab. temp_offset ist vom Typ Double. Offset und die anderen Variablen sind nun Extended. Leider wird immer noch falsch "abgeschnitten"

Uwe Raabe 18. Mär 2010 17:31

Re: trunc liefert nicht das erwartete Ergebnis
 
Was der Debugger anzeigt, ist nicht immer exakt der interne Wert. Es ist also durchaus möglich, daß x=0.61 da steht, nach einem trunc(100*x) aber nur 60 übrig bleibt.

Bist du dir sicher, daß du wirklich nach der zweiten Kommastelle abschneiden oder doch lieber runden willst? Beim Abschneiden würde nämlich 0.609 auch nur 0.60 ergeben. Fürs Runden kannst du einfach 0.01*Round(100*x) nehmen. Das gibts auch schon in D5.

Medium 18. Mär 2010 18:36

Re: trunc liefert nicht das erwartete Ergebnis
 
Jede Woche auf's Neue das selbe Thema. Es wäre ja doch sinnvoll, wenn man als Programmierer wüsste womit man da so unbedarft hantiert, und was dabei so alles passieren kann - z.B. die Binärdarstellung von gebrochenen Zahlen, die wie fast alles im Leben auch so ihre Eigenarten mit sich bringt. Würde man dieses Handwerkszeug kennen, müsste man diese Frage nicht stellen. (Bei Google suchenGleitkommazahl) Die DP Suche sollte zu dem Thema auch haufenweise Threads mit mannigfaltig Erklärungen liefern, teils sogar mit Beispielrechnungen und allem.

blink182 18. Mär 2010 18:41

Re: trunc liefert nicht das erwartete Ergebnis
 
Das liegt halt an der internen Darstellung von Gleitkommazahlen.
IEEE 754 ;)
http://www.h-schmidt.net/FloatApplet/IEEE754de.html z.b.
was dezimal 0.61 ist, ist mit Doublegenauigkeit noch lange nicht 0.61, sondern 0.6100000143051147 -> also muss exakte
von 0.61d etwas kleiner sein als 0.61 und wird somit, mit trunc(x*100) als 60 interpretiert...

Daimonion 23. Mär 2010 15:03

Re: trunc liefert nicht das erwartete Ergebnis
 
Zitat:

Zitat von blink182
Das liegt halt an der internen Darstellung von Gleitkommazahlen.
IEEE 754 ;)
http://www.h-schmidt.net/FloatApplet/IEEE754de.html z.b.
was dezimal 0.61 ist, ist mit Doublegenauigkeit noch lange nicht 0.61, sondern 0.6100000143051147 -> also muss exakte
von 0.61d etwas kleiner sein als 0.61 und wird somit, mit trunc(x*100) als 60 interpretiert...


Nun ja, so was in der Art wird es sein. Ich werd eine für mich geeignete Lösung finden!

stoxx 23. Mär 2010 16:35

Re: trunc liefert nicht das erwartete Ergebnis
 
Zitat:

Nun ja, so was in der Art wird es sein. Ich werd eine für mich geeignete Lösung finden!
vielleicht ist ja die Funktion "RoundTo" aus der unit Math genau das, was Du suchst ;-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:57 Uhr.
Seite 1 von 2  1 2      

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