Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Trunc liefert falschen Wert (https://www.delphipraxis.net/183235-trunc-liefert-falschen-wert.html)

devidespe 22. Dez 2014 16:31

Delphi-Version: XE

Trunc liefert falschen Wert
 
Hallo,

irgendwie scheint Trunc bei mir nicht ganz korrekt zu rechnen. Wenn ich einen Real-Wert von 9.7 x 10 multipliziere und daraus einen Integer mache, sollte es 97 sein, Trunc macht daraus aber 96:

Delphi-Quellcode:
var ErgTemp : Real;
    ErgTempInt : Integer;
begin
  ErgTemp:=9.7;
  ErgTempInt:=Trunc(ErgTemp * 10);
  ShowMessage(IntToStr(ErgTempInt));
end;
Hat jemand eine Idee, woran das liegen könnte? Vielen Dank.

Medium 22. Dez 2014 16:39

AW: Trunc liefert falschen Wert
 
Hier im Forum suchenfloats ungenauigkeit

-> Nimm besser Round()

Mavarik 22. Dez 2014 17:26

AW: Trunc liefert falschen Wert
 
Deswegen:

Delphi-Quellcode:
var ErgTemp : Real;
     ErgTempInt : Integer;
begin
   ErgTemp:=9.7;
   ErgTemp := ErgTemp * 10;
   ErgTempInt:=Trunc(ErgTemp);
   ShowMessage(IntToStr(ErgTempInt));
end;
Mavarik

Der schöne Günther 22. Dez 2014 18:02

AW: Trunc liefert falschen Wert
 
Also ich kriege wie erwartet 97 raus 8-)

mm1256 22. Dez 2014 18:16

AW: Trunc liefert falschen Wert
 
Komisch...
Delphi-Quellcode:
var ErgTemp : Real;
    ErgTempInt : Integer;
begin
  ErgTemp:=9.7;
  ErgTempInt:=Trunc(ErgTemp * 10);
  ShowMessage(IntToStr(ErgTempInt));
end;
...gibt bei mir auch 96. Warum das bei dir 97 sind, ist mir ein Rätsel :roll:

Der schöne Günther 22. Dez 2014 18:19

AW: Trunc liefert falschen Wert
 
Oh, es wird wieder lustig. Herzlich Willkommen zu einer neuen Ausgabe von

Compiler - Magic


Auf Win64 kommt bei mir 97 heraus. Bei Win32 kommt 96 heraus. Wer probiert iOS und Android aus?

Insider2004 22. Dez 2014 18:50

AW: Trunc liefert falschen Wert
 
9.7*10=96.999999999999999 -> trunc -> 96.

stimmt doch! bitte lesen: Dezimalsysten <-> Binärsystem

mm1256 22. Dez 2014 19:16

AW: Trunc liefert falschen Wert
 
Und warum dann mit Win32 und Win64 zwei unterschiedliche Werte. Hab es soeben auch nachvollziehen können.

p80286 22. Dez 2014 19:22

AW: Trunc liefert falschen Wert
 
Darf ich mal dezent auf #2 hinweisen?
oder anders herum trunc(96.9999999999999999999) ist nun mal 96 und trunc(97.0000000000000000001) ist 97!

Gruß
K-H

Insider2004 22. Dez 2014 19:28

AW: Trunc liefert falschen Wert
 
Zitat:

Zitat von mm1256 (Beitrag 1284420)
Und warum dann mit Win32 und Win64 zwei unterschiedliche Werte. Hab es soeben auch nachvollziehen können.

Real darfst du nicht nehmen. Nur Double. Auch nich Extended.

mkinzler 22. Dez 2014 19:30

AW: Trunc liefert falschen Wert
 
Extended ist das Selbe wie Double bei 64Bit. Kann man also schon nehmen.

Uwe Raabe 22. Dez 2014 19:32

AW: Trunc liefert falschen Wert
 
Zitat:

Zitat von mkinzler (Beitrag 1284426)
Extended ist das Selbe wie Double bei 64Bit. Kann man also schon nehmen.

In der Standardeinstellung gilt das auch für Real: Real48-Kompatibilität (Delphi)

himitsu 22. Dez 2014 20:13

AW: Trunc liefert falschen Wert
 
Extended sollte man besser nicht verwenden ... es war eigentlich nur für's Rechnen vorgesehen und zum Speichern Single oder Double.

Real ist sowas wie Integer/NativeInt und String und ist nur ein Alias auf den "aktuellen" Typen.

Der uralte Real48-Typ sollte besser auch nicht mehr verwendet werden, außer für Abwärtskompatibilitäten, genauso wie Comp.

Dejan Vu 22. Dez 2014 21:41

AW: Trunc liefert falschen Wert
 
Wieso sollte man Extended nicht nehmen? Und wofür 'nicht'?

Uwe Raabe 22. Dez 2014 22:03

AW: Trunc liefert falschen Wert
 
Zitat:

Zitat von Dejan Vu (Beitrag 1284453)
Wieso sollte man Extended nicht nehmen? Und wofür 'nicht'?

Da Extended unter Win64 einem Double gleichkommt, bekommst du ab und an unterschiedliche Ergebnisse zu einem Win32 Compilat. Solange man nur für Win32 compiliert oder die Berechnungen unempfindlich gegebüber diesen Änderungen gestaltet, kann man Extended natürlich verwenden.

Medium 23. Dez 2014 07:35

AW: Trunc liefert falschen Wert
 
Es ist aber an sich auch völlig Hupe welchen Float man jetzt nimmt, da prinzipiell alle irgendwann solche Ergebnisse produzieren. Vielleicht nicht bei 9,7*10, aber dann eventuell bei 3,1*20 oder wann auch immer. Trunc() ist, wenn man eigentlich runden will, einfach die falsche Funktion. Und dann ist es auch schon wieder fast egal welchen Float-Typen man wählt (zumindest für diesen Schritt).

Wenn es dennoch keine Rundung sein soll, sondern ein Floor(), und es kommt wirklich darauf an, dass es immer wirklich genau richtig wird, dann wird Bei Google suchenFixpunktarithmetik eigentlich schon fast zur Pflicht.

Dejan Vu 23. Dez 2014 08:02

AW: Trunc liefert falschen Wert
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1284462)
Da Extended unter Win64 einem Double gleichkommt, bekommst du ab und an unterschiedliche Ergebnisse zu einem Win32 Compilat. Solange man nur für Win32 compiliert oder die Berechnungen unempfindlich gegebüber diesen Änderungen gestaltet, kann man Extended natürlich verwenden.

Die Unterschiede sind in den letzten Stellen zu finden, also der 14-16 Stelle. Und selbst in Iterationen blubbert der Fehler in die maximal 12 Stelle. Ich kann mir kein ernsthaftes Programm vorstellen, dass sich auf die letzten Stellen einer Berechnung verlässt, i.a. werden max. 6-8 Stellen verwendet.

Klar, auf dem Papier kommt ab und an etwas unterschiedliches heraus, aber das als Grund zu nehmen, auf Extended lieber zu verzichten, geht dann doch etwas zu weit. Das klingt nach Schlangenöl.

himitsu 23. Dez 2014 08:11

AW: Trunc liefert falschen Wert
 
Wenn ich das richtig verstanden hab, dann war Extended nie für den öffentlichen Gebrauch gedacht,
drum trifft man das in anderen Programmiersprachen auch so selten an. :stupid:

http://docwiki.embarcadero.com/Libra...ystem.Extended

Diese Rundungsfehler muß man bei allen Größen beachten und immer nur das größte zu verwenden ist auch keine Lösung.

Dejan Vu 23. Dez 2014 09:02

AW: Trunc liefert falschen Wert
 
Zitat:

Zitat von himitsu (Beitrag 1284480)
Diese Rundungsfehler muß man bei allen Größen beachten und immer nur das größte zu verwenden ist auch keine Lösung.

Nein, aber es gibt Berechnungen, bei denen die Double Genauigkeit nicht ausreicht, ich aber noch nicht auf eine BCD-Lösung ausweichen muss, die dann einen erheblichen Geschwindkeitsnachteil mit sich bringt.

Ich müsste in meinen Unterlagen stöbern, aber es gab einige Fälle, bei denen ich ganz froh war, Extended verwenden zu können.

Weiterhin mag es sein, das Extended mal nur intern gedacht war, aber ... WTF. Teflon wurde ursprünglich auch nur für die Raumfahrt entwickelt und heute brätst Du deine Spiegeleier drauf (:gruebel: was soll uns dieses Gleichnis kurz vor Weihnachten sagen?)

Uwe Raabe 23. Dez 2014 09:55

AW: Trunc liefert falschen Wert
 
Zitat:

Zitat von Dejan Vu (Beitrag 1284482)
Nein, aber es gibt Berechnungen, bei denen die Double Genauigkeit nicht ausreicht, ich aber noch nicht auf eine BCD-Lösung ausweichen muss, die dann einen erheblichen Geschwindkeitsnachteil mit sich bringt.

Ich müsste in meinen Unterlagen stöbern, aber es gab einige Fälle, bei denen ich ganz froh war, Extended verwenden zu können.

Natürlich darfst du Extended verwenden, um die erhöhte Genauigkeit auszunutzen. Es ist manchmal ganz praktisch, wenn man Double-Werte speichert, intern aber mit Extended rechnen kann. Ich verwende das selbst auch für meine CAD/CAM-Anwendungen.

Mit der Genauigkeit ist das allerdings so eine Sache. Gerade bei trigonometrischen Berechnungen muss man seine Genauigkeitsfenster beim Wechsel von Double zu Extended etwas weiter machen. Das hatte z.B. den Effekt, daß meine Unit-Tests für diese Berechnungen beim Umstieg von 32 auf 64 Bit zunächst nicht mehr durchliefen. Ist nichts Unlösbares, aber man muss halt darauf eingehen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:02 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