Delphi-PRAXiS
Seite 3 von 3     123

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   FloatToStrF Rundungsfehler ? (https://www.delphipraxis.net/206772-floattostrf-rundungsfehler.html)

Incocnito 4. Feb 2021 16:35

AW: FloatToStrF Rundungsfehler ?
 
Klingt als würde da ein Modul eine globale Einstellung ändern ...
TFormatSettings oder sowas.

Hilft denn mein Tipp nicht, um zuverlässig immer das gleiche Ergebnis zu erhalten?

LG Incocnito

egentur 4. Feb 2021 17:00

AW: FloatToStrF Rundungsfehler ?
 
Hallo Incocnito

Doch , danke

Ich werde da die Messwerte immer als string mit 5 Nachkommastellen geliefert werden
nach der Konvertierung in double 0.000001 addieren
dann futionierts auch mit floattostrf(x,fffixed,6,4)

Ich musste das so machen weil der User die Nachkommastellen in seinem Grid/Report individuell einstellen wollte.


aber denoch würde ich gerne den Grund wissen !!

Incocnito 5. Feb 2021 10:02

AW: FloatToStrF Rundungsfehler ?
 
Vielleicht wurde in der Routine auch an dem CPU FloatingPoint ControlWord herumgefummelt.

vgl.
https://www.intel.com/content/dam/ww...l-1-manual.pdf
8.1.5 x87 FPU Control Word

Obwohl mir die Auswirkungen jetzt nicht bekannt sind.
Auf dem ersten Blick scheint es nur bei SSE- und SSE2-CPU-Funktionen relevant zu sein.
Fraglich, ob die an der Stelle überhaubt benutzt werden.

Du könntest zum Testen das ControlWord jeweils vorher auslesen.
(System.Get8087CW()) und prüfen ob irgendwelche Aufrufe vom QuickReport
da etwas ändern. Wir mussten feststellen, dass beim Arbeiten mit der Apollo-Datenbank
eine Funktion da was verstellt.

Ich hoffe diese Information hilft weiter.

Liebe Grüße
Incocnito

egentur 5. Feb 2021 12:33

AW: FloatToStrF Rundungsfehler ?
 
Hallo Incocnito

In der Tat.

Beim ersten Durchlauf ergibt System.Get8087CW()

den Wert 4722 und bleibt bestehen ( hier rundet floattostrf(rv,fffixed,6,4) den Double Wert von 0.500149999999999983 auf 0,5002)

bis ich aus dem PrintPreview den Ausdruck auf den Drucker (unabhängig vom Druckertyp) wähle

danach ergibt System.Get8087CW()
den Wert 4978 und von da an wird korrekt gerundet also ( floattostrf(rv,fffixed,6,4) den Double Wert von 0.500149999999999983 auf 0,5001)

Gibt es dann hier eine Lösung ausser deiner beschriebenen ?

Achim Kalwa 5. Feb 2021 14:41

AW: FloatToStrF Rundungsfehler ?
 
Zitat:

Zitat von egentur (Beitrag 1482337)
Beim ersten Durchlauf ergibt System.Get8087CW() den Wert 4722 [...]
bis ich aus dem PrintPreview den Ausdruck auf den Drucker (unabhängig vom Druckertyp) wähle
danach ergibt System.Get8087CW()

Auf genau diese Problematik hatte doch Der schöne Günther in Beitrag #3 schon hingewiesen:
Zitat:

Ist das wieder der Mythos mit den Druckertreibern welche die FPU-Einstellungen verdrehen?
Scheint also doch kein Mythos zu sein... Oder doch ein Problem von QuockReport?

Delphi.Narium 5. Feb 2021 14:52

AW: FloatToStrF Rundungsfehler ?
 
http://docwiki.embarcadero.com/Libra...stem.Set8087CW

http://docwiki.embarcadero.com/CodeE...087CW_(Delphi)

Demnach müsste 4978 der Defaultwert sein und die 4722 die Folge irgendeiner Änderung. Keine Ahnung wie man herausbekommt, woraus sie resultiert.

Eventuell mal alle Sourcen durchsuchen, ob irgendwo Set8087CW aufgerufen wird und welcher Wert dort gesetzt wird.

Wenn da nix zu finden ist, wird das von "irgendeiner Software / irgendeinem Treiber / ..." verändert.

Fraglich ist hierbei: Welche Nebenwirkungen entstehen, wenn Du selbst per Set8087CW(4972) den Wert setzt. Wer wie was auch immer die 4722 setzt, macht das (vermutlich) aus 'nem betimmten Grund und nicht nur "Just For Fun" :-(

Edit:

Ein "ungünstiger" Aufruf von SetPrecisionMode aus der Unit Math könnte eventuell auch eine unerwünschte Nebenwirkung haben.

Incocnito 5. Feb 2021 15:30

AW: FloatToStrF Rundungsfehler ?
 
Hier
http://docwiki.embarcadero.com/Libra....Default8087CW
steht, dass der Default-Wert $1332 also 4714 sein soll.

Aber auch bei mir ist beim Start dort schon ein anderer Wert enthalten.
Indy? QuickReport? Apollo Datenbank? Jedi? Keine Ahnung, wer den Wert verstellt.

Für deinen Fall:
4722 = 0001 0010 0111 0010
Rounding Contol = 00
Precission Control = 10 = Double Pressision 53bits
---
4978 = 0001 0011 0111 0010
Rounding Contol = 00
Precission Control = 11 = Double Extended Pressision 64bits

Eine höhere Genauigkeit führt hier nur zu einem anderen Ergebnis.
Meiner Meinung nach wird zwar bei erhöhter Genauigkeit mathematisch richtig rundet,
aber bei Einschaltung des gesunden Menschenverstandes eher falsch rundet.
Aufgerundet wird ja immer bei "5", aber durch die "Ungenauigkeit" des
PC steht dort "4,99999999", also muss ich trotzdem aufrunden, eben
weil das ja nur ein falscher Ausgagswert Aufgrund der technischen Gegebenheiten ist.
Außerdem um darauf wieder zurück zu kommen ist das jetzt der Fall für
deine 0,50015 ... für andere Zahlen sieht das wieder anders aus und du kannst
nicht "alle" Möglichkeiten testen (behaupte ich mal).

Das unterschiedliche Verhalten kann also durch das 8087 ControlWord erklärt werden.
Trotzdem empfehle ich (wie du es ja schon gemacht hast) das einfach zu umgehen.

LG Incocnito

egentur 5. Feb 2021 16:04

AW: FloatToStrF Rundungsfehler ?
 
Danke an Incocnito und alle anderen

Ich habe auch im Source keine Stelle gefunden wo das explizit umgestellt wird.

Ich mach dann mal +0.000001

Schöne Grüße :-D

egentur 5. Feb 2021 16:39

AW: FloatToStrF Rundungsfehler ?
 
Kurzer Nachtrag

Ich hab doch noch eine DLL gefunden, die für die serielle Schnittstelle zu einem bestimmten
Messgeräte verwendet wird, und die verstellt den Wert !

Natürlich ohne source von extern :cry:

Aber wenn man endlich weiß :-D


Alle Zeitangaben in WEZ +2. Es ist jetzt 07:51 Uhr.
Seite 3 von 3     123

Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf