Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Nachkommastellen von Extended abschneiden um Integer zu erhalten (https://www.delphipraxis.net/215201-nachkommastellen-von-extended-abschneiden-um-integer-zu-erhalten.html)

Uwe Raabe 27. Mai 2024 15:30

AW: Nachkommastellen von Extended abschneiden um Integer zu erhalten
 
Es kommt halt drauf an, wie hoch der Nachkommastellenwert gehen kann bevor er abgeschnitten werden soll. Wir wissen ja noch nichts über die Bedeutung dieser Werte und was mit dem Abschneiden erreicht werden soll. Wenn ein Wert z.B. ungefähr 4.999999999 entspricht, soll das dann wirklich 4 werden oder gilt das dann eher als 5?

himitsu 27. Mai 2024 15:41

AW: Nachkommastellen von Extended abschneiden um Integer zu erhalten
 
Abgesehn davon, dass Extended "ursprünglich" nie dafür gedacht war von Entwicklern zur Speicherung genutzt zu werden,
weswegen es das anfangs in vielen anderen Sprachen (C++) garnicht gab, bzw. teilweise immernoch nicht gibt.

Merkt man jetzt, dass es in Bezug auf Win64 und Multiplatform (Android/iOS) wieder nicht mehr gibt.

Kann man von der Verwendung von Extended sowieso nur ausdrücklich von abraten.


Delphi-Quellcode:
Value := 24.1 * 10; // löst der Compiler auf und nimmt direkt 241.0


Value := 24.1;
Value := Value * 10; // wird erst zur Laufzeit gerechnet (mit den aktuellen Möglichkeiten und Einstellungen der FPU)
Schon erklärt sich, warum vermeintlich "Identisches" eigentlich nur annähernd gleich ist
und sich somit doch unterscheiden kann,
vor allem in Bezug darauf, wann und wie bezüglich der Ungenauigkeiten von Fließkommazahlen es sich leicht abweichen muß.

241.00000000…001
241.00000000…000
241.99999999…999

dummzeuch 27. Mai 2024 16:32

AW: Nachkommastellen von Extended abschneiden um Integer zu erhalten
 
Zitat:

Zitat von himitsu (Beitrag 1537203)
Abgesehn davon, dass Extended "ursprünglich" nie dafür gedacht war von Entwicklern zur Speicherung genutzt zu werden,
weswegen es das anfangs in vielen anderen Sprachen (C++) garnicht gab, bzw. teilweise immernoch nicht gibt.

Merkt man jetzt, dass es in Bezug auf Win64 und Multiplatform (Android/iOS) wieder nicht mehr gibt.

Kann man von der Verwendung von Extended sowieso nur ausdrücklich von abraten.

Das würde aber hier keinen Unterschied machen, da dasselbe Problem auch mit Single oder Double auftritt.

Uwe Raabe 27. Mai 2024 16:44

AW: Nachkommastellen von Extended abschneiden um Integer zu erhalten
 
Das Problem ist hier eigentlich die Verwendung von Trunc statt Round bzw. RoundTo. Zur internen Darstellung einer Float-Zahl wird die nächstgelegene Zahl verwendet, die mit der aktuellen Auflösung darstellbar ist. In den Fällen, wo das nicht exakt machbar ist, kann die dargestellte Zahl kleiner oder größer als die gewünschte Zahl sein, je nachdem welche näher dran liegt. Bei einer kleineren Zahl liefert ein Trunc dann aber nicht das erwartete Ergebnis.

Leider gibt es kein Allheilmittel für dieses Problem, da es immer von der aktuellen Bedeutung der Zahl und deren Verwendung abhängt. Unter der Annahme, dass eine Genauigkeit von zwei Nachkommastellen ausreicht, kann man ein RoundTo auf die zwei Stellen machen und darauf dann das Trunc loslassen. Alternativ multipliziert man mit 1000, macht ein Round auf Integer mit anschließendem DIV 10. Es gibt viele Wege, aber für alle braucht es etwas Kontext.

Kostas 27. Mai 2024 19:23

AW: Nachkommastellen von Extended abschneiden um Integer zu erhalten
 
Meine Zahlen haben einen Bereich von 0.0 bis 799.99. Die Zahlen kommen von Maschinen die dessen Werte über RS232 senden. Je nachdem wie die Maschine eingestellt ist, werden die Werte mit einer oder zwei Nachkommastellen gesendet. Die einzelnen Werte werden zu einem Gesamtergebnis addiert. Jetzt kann es vorkommen dass die Maschine ein- oder zweistellig sendet und das Ergebnis jedoch OHNE der Nachkommazahl addiert werden soll. Wenn das Ergebnis als Ganzzahl benötigt wird ist das Ergebnis bei 9.1 + 9.9 = 18 als NUR 9 + 9. Wenn das Ergebnis mit einer Nachkommastelle benötigt wird, dann muss das Ergebnis 9.1 + 9.9 = 19 sein. Ich habe also wirklich die Anforderung nicht zu runden sondern bei Bedarf die Nachkommastellen abzuschneiden.

himitsu 27. Mai 2024 19:34

AW: Nachkommastellen von Extended abschneiden um Integer zu erhalten
 
Delphi-Referenz durchsuchenSystem.Currency :stupid: http://docwiki.embarcadero.com/RADSt...)#Reelle_Typen
Delphi-Referenz durchsuchenSystem.Extended
Delphi-Referenz durchsuchenBCD (https://www.sps-lehrgang.de/bcd-code/)


PS:
{$EXTENDEDCOMPATIBILITY OFF}
{$EXCESSPRECISION ON}
http://docwiki.embarcadero.com/RADSt...e_Applications
...

Uwe Raabe 27. Mai 2024 21:08

AW: Nachkommastellen von Extended abschneiden um Integer zu erhalten
 
Wenn die Werte schon mit nur bis zu zwei Nachkommastellen ankommen, dann könntest du die ja auch als Currency speichern. Das ist ja so wie Integer mit (bis zu vier) Nachkommastellen. Multiplizieren und Dividieren passiert dann ja offenbar nicht und wenn es dann nach dem Trunc erstmal Integer sind, ist ja eh alles easy.

jaenicke 28. Mai 2024 01:16

AW: Nachkommastellen von Extended abschneiden um Integer zu erhalten
 
Zitat:

Zitat von Kostas (Beitrag 1537216)
Meine Zahlen haben einen Bereich von 0.0 bis 799.99. Die Zahlen kommen von Maschinen die dessen Werte über RS232 senden.

Bei solchen Protokollen werden die Zahlen oft als String übertragen. Ist das auch hier der Fall? Wenn ja, dann speichere die Werte einfach als Integer vor dem Komma plus Nachkommateil ebenfalls als Integer.

Wenn du keine Fließkommazahlen verwendest, vermeidest du auch alle Probleme in der Richtung. Solange du nur addieren musst, kannst du das alles vollkommen problemlos mit Integerwerten umsetzen.

dummzeuch 28. Mai 2024 07:49

AW: Nachkommastellen von Extended abschneiden um Integer zu erhalten
 
Zitat:

Zitat von jaenicke (Beitrag 1537224)
Zitat:

Zitat von Kostas (Beitrag 1537216)
Meine Zahlen haben einen Bereich von 0.0 bis 799.99. Die Zahlen kommen von Maschinen die dessen Werte über RS232 senden.

Bei solchen Protokollen werden die Zahlen oft als String übertragen. Ist das auch hier der Fall? Wenn ja, dann speichere die Werte einfach als Integer vor dem Komma plus Nachkommateil ebenfalls als Integer.

Oder den Wert * 100, was bei dem Wertebereich problemlos in einen Integer passt (Int16 ist out, ebenso UInt16, wegen des Wertebereichs).

Dann erhält man die ganzzahligen Werte mittels div 100 und die Nachkommastellen mittels mod 100.
Und wenn man addiert, erhält man wieder eine Zahl, für die dasselbe gilt.

Bei halbwegs modernem Delphi kann man das sogar in einen enhanced Record packen.

Amateurprofi 28. Mai 2024 16:57

AW: Nachkommastellen von Extended abschneiden um Integer zu erhalten
 
Zitat:

Zitat von himitsu (Beitrag 1537201)
Zitat:

+0.5
Bei 0.9 würde dann aber +1 rauskommen.

Trunc(1.9) = 1
Trunc(1.9+0.5) = 2


Aber ja, ein +0.00…001 und dann Trunc, wäre eine mögliche Lösung, allerdings nur, wenn es kleiner ist, als real vorkommende Nachkommastellen.
Oder vielleicht auch ein RoundTo mit einem passenden SetFPURoundMode.
Oder ...

Recht hast Du.
Ausrede für Helden: Es ging um 24.1*10, nicht um 1.9.


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

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