AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Rundungs-Probleme bei Ausgabe als String
Thema durchsuchen
Ansicht
Themen-Optionen

Rundungs-Probleme bei Ausgabe als String

Ein Thema von raller09 · begonnen am 15. Feb 2018 · letzter Beitrag vom 16. Feb 2018
Antwort Antwort
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#1

AW: Rundungs-Probleme bei Ausgabe als String

  Alt 15. Feb 2018, 19:33
Hallo,

Zitat:
Erst wenn ich die Rundungs-Funktion mit "lAnzahlNachkommaStellen + 1" aufrufe, scheint es so, dass ich ein reproduzierbares Ergebnis bekomme...
Das ist genau der richtige Ansatz!
Ich wollte gerade sagen. Das kann es nicht sein, dass man für eine solche Funktion der Maßen tief in den Prozessorinstruktionen eingreifen muss. Wenn das der Fall ist, dann macht man irgendwas verkehrt.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
raller09

Registriert seit: 7. Nov 2005
38 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#2

AW: Rundungs-Probleme bei Ausgabe als String

  Alt 16. Feb 2018, 07:40
Darfst du schon. Das X87 Control Word besteht aus mehreren Bits, die unterschiedliche Bedeutungen haben.
Nähere Infos dazu entnimmst du am besten der "Intel Architecture Software Developer's Manual; Vol I: Basic Architecture".

Was RC angeht, sind hier die relevanten Werte:
Code:
Round to nearest even      = $00B
Round down toward infinity = $01B
Round up toward infinity   = $10B
Round toward zero (trunc)  = $11B
Habe gesten nachmittag auch das Dokument noch gefunden. Ist dort recht gut erklärt.

Kann gut sein, dass nur die Exception Masks geändert wurden. Ich schaue mal nach .. Edit: Ja genau z.b. zwischen 4991 und 4962 ändern sich nur die Exception Masks.
Hier mal die Bit-Schreibweise meiner Werte:
Code:
                                      keine Berücksichtigung
Dec    Hex       C RC  Exception  von mir
4991    137F   0001 0011 0111 1111   Delphi vor erster Start
 610     262           10 0110 0010   nach 1. Aufruf
 610     262           10 0110 0010   folgende Aufrufe

                   I  PC            Schutz mit try ...
Dec    Hex       C RC  Exception  finally
4991    137F   0001 0011 0111 1111   Delphi vor erster Start
 610     262           10 0110 0010   nach 1. Aufruf
4962    1362    0001 0011 0110 0010   folgende Aufrufe

                   I  PC            Schutz mit try...
Dec    Hex       C RC  Exception  finally + Setzen "37F"
4991    137F   0001 0011 0111 1111   Delphi vor erster Start
 895     37F          11 0111 1111   manuell gesetzt
 610     262           10 0110 0010   nach 1. Aufruf
 895     37F          11 0111 1111   manuell gesetzt
 866     362           11 0110 0010   folgende Aufrufe

                   I  PC            Schutz mit try...
Dec    Hex       C RC  Exception  finally + Setzen "262"
4991    137F   0001 0011 0111 1111   Delphi vor erster Start
 610     262           10 0110 0010   manuell gesetzt
 610     262           10 0110 0010   nach 1. Aufruf
 610     262           10 0110 0010   manuell gesetzt
 610     262           10 0110 0010   folgende Aufrufe
Fazit:
  • die Dll setzt sich immer die gleiche Exception Mask
  • Der Rundungs-Modus (RC) wird nicht geändert
  • Infinity wird zwar geändert, spielt aber entsprechend der Dokumentation aus dem Link keine Rolle:
    Zitat:
    8.1.6 Infinity Control Flag
    The infinity control flag (bit 12 of the x87 FPU control word) is provided for compatibility with the Intel 287 Math
    Coprocessor; it is not meaningful for later version x87 FPU coprocessors or IA-32 processors. See Section 4.8.3.3,
    “Signed Infinities,” for information on how the x87 FPUs handle infinity values.
    Ist der Wert also jetzt egal?
  • es gibt ggf. eine Abweichung bei Precision Control (PC), mögliche Werte
    Code:
    Precision                          PC Field
    Single Precision (24 bits)         00B
    Reserved                           01B
    Double Precision (53 bits)         10B
    Double Extended Precision (64 bits) 11B
    -> erster Aufruf läuft immer auf "Double Precision", folgende auf "Double Extended Precision", falls der vorherige Wert nicht übereinstimmt. Ich habe mir nicht die genauen Gründe angesehen. Das werde ich mit den Erstellern der dll abklären. Wenn ich dort einfach auch "262" setze, dann wird der Wert nicht geändert.
  • Durch die .dll wird die Eigenschaft des "x87 FPU Control Word" für das Programm verstellt, ich muss/sollte also mir vorher den Wert merken und ich nachher zurücksetzen.

Zitat:
Erst wenn ich die Rundungs-Funktion mit "lAnzahlNachkommaStellen + 1" aufrufe, scheint es so, dass ich ein reproduzierbares Ergebnis bekomme...
Das ist genau der richtige Ansatz!
Ich wollte gerade sagen. Das kann es nicht sein, dass man für eine solche Funktion der Maßen tief in den Prozessorinstruktionen eingreifen muss. Wenn das der Fall ist, dann macht man irgendwas verkehrt.
Das wäre mir auch lieber. Aber es hat sich leider bei mir gezeigt, dass auch mit der Rundung andere Ergebnisse (an anderer Stelle) von den "Format" und "ToStr"- Funktionen ausgegeben werden (also wird das Round... schon irgendwie anders arbeiten).
Daher ist das "try ... finally" zum "Merken und Zurücksetzen" schon notwendig, denke ich.


Vielen Dank für eure Hilfe!
  Mit Zitat antworten Zitat
Fritzew

Registriert seit: 18. Nov 2015
Ort: Kehl
678 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Rundungs-Probleme bei Ausgabe als String

  Alt 16. Feb 2018, 08:27
Also wenn es sogar im Header der Dll so vermerkt ist, solltest Du meiner Meinung nach bei Aufrufen in die Dll so verfahren:

// Nur so hingetipt Pseudo Code

Delphi-Quellcode:
Procedure callToDll ;
begin
  Set8087CW(DllCW); // DllCw = CtrlWord das die Dll erwartet
  CallToDll;
  Set8087CW(MYCW); // Das was Du erwartest
end;
Einfach um sicher zu gehen das die Dll auch sauber arbeitet und davon ausgeht das immer "Ihr" Wert gesetzt ist
Fritz Westermann
  Mit Zitat antworten Zitat
raller09

Registriert seit: 7. Nov 2005
38 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#4

AW: Rundungs-Probleme bei Ausgabe als String

  Alt 16. Feb 2018, 08:34
Also wenn es sogar im Header der Dll so vermerkt ist, solltest Du meiner Meinung nach bei Aufrufen in die Dll so verfahren:

// Nur so hingetipt Pseudo Code

Delphi-Quellcode:
Procedure callToDll ;
begin
  Set8087CW(DllCW); // DllCw = CtrlWord das die Dll erwartet
  CallToDll;
  Set8087CW(MYCW); // Das was Du erwartest
end;
Einfach um sicher zu gehen das die Dll auch sauber arbeitet und davon ausgeht das immer "Ihr" Wert gesetzt ist
genau das mache ich jetzt ja auch. Ich benutze nur nicht den "dokumentierten" Wert. Sondern den, der sich bei meinen Versuchen als "gleich" gezeigt hat. Dokumentation ist schon etwas älter, da ist mittlerweile auch der Compiler der .dll gewechselt worden...

Danke,
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#5

AW: Rundungs-Probleme bei Ausgabe als String

  Alt 16. Feb 2018, 12:47
Ach das steht so in der Doku der DLL? Was macht die um Gottes Willen für komische Sachen.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
freimatz

Registriert seit: 20. Mai 2010
1.513 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Rundungs-Probleme bei Ausgabe als String

  Alt 16. Feb 2018, 14:40
wäre da nicht auch noch ein try finally sinnvoll
  Mit Zitat antworten Zitat
Fritzew

Registriert seit: 18. Nov 2015
Ort: Kehl
678 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Rundungs-Probleme bei Ausgabe als String

  Alt 16. Feb 2018, 16:24
wäre da nicht auch noch ein try finally sinnvoll
Nee.....
Wenn eine Exception in der Dll auftritt hast Du ganz andere Probleme
da kannst Du Dir das finally echt sparen. Exceptions aus anderen Compilern und oder Sprachen sind eh nicht kompatibel zu Delphi.

Ach das steht so in der Doku der DLL? Was macht die um Gottes Willen für komische Sachen.
Für das ist das FPU Controlword ja da. Bei gemixten Application/Dll muss man dann schon dafür sorgen das alle glücklich sind.
Da es in dieser speziellen Dll ja sogar dokumentiert ist, einfach daran halten.
Fritz Westermann
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#8

AW: Rundungs-Probleme bei Ausgabe als String

  Alt 16. Feb 2018, 16:52
wäre da nicht auch noch ein try finally sinnvoll
Nee.....
Wenn eine Exception in der Dll auftritt hast Du ganz andere Probleme
da kannst Du Dir das finally echt sparen. Exceptions aus anderen Compilern und oder Sprachen sind eh nicht kompatibel zu Delphi.
Delphi benutzt SEH zum Fangen von Exceptions. Das heißt, dass sämtliche CPU Exceptions grundsätzlich gefangen werden können; auch dann, wenn sie in einer fremden DLL auftreten. Ob man den State daraus dann noch sinnvoll recovern kann, ist allerdings fragwürdig. Höher-Sprachige Exceptions sind in vielen Fällen auch damit behandelbar. C++ Exceptions z.b. erzeugen am Ende tatsächlich auch eine spezielle CPU Exception. Delphi wird zwar den Typ nicht mehr differenzieren können, aber die Exception ansich bekommst du mit.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Fritzew

Registriert seit: 18. Nov 2015
Ort: Kehl
678 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Rundungs-Probleme bei Ausgabe als String

  Alt 16. Feb 2018, 16:55
Delphi benutzt SEH zum Fangen von Exceptions. Das heißt, dass sämtliche CPU Exceptions grundsätzlich gefangen werden können; auch dann, wenn sie in einer fremden DLL auftreten. Ob man den State daraus dann noch sinnvoll recovern kann, ist allerdings fragwürdig. Höher-Sprachige Exceptions sind in vielen Fällen auch damit behandelbar. C++ Exceptions z.b. erzeugen am Ende tatsächlich auch eine spezielle CPU Exception. Delphi wird zwar den Typ nicht mehr differenzieren können, aber die Exception ansich bekommst du mit.
Das ist aber im Regelfall das letzte was Du mitbekommst, stabil ist was anderes.
Fritz Westermann
  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:11 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz