Delphi-PRAXiS
Seite 1 von 3  1 23      

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)

Kostas 26. Mai 2024 17:43

Delphi-Version: 5

Nachkommastellen von Extended abschneiden um Integer zu erhalten
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hallo Zusammen,

ich habe jetzt mit dem bekannten Problem von 0.1 bei Extended Zahlen zu kämpfen.

Zur Entwurfszeit steht der Cursor auf AIMINGRESULT und hat de Wert 24.1 * 10 sollte eigentlich 241 ergeben. Mit Trunc möchte ich danach den Extended in ein Integer umwandeln um die 241 als Integer in die DB zu schrieben. Doch aus 24.1 * 10 ergibt nicht 241 sondern 240.

Hat jemand eine Idee ich ich zuverlässig aus einem Extended mit 10 multiplizieren kann und danach evl. vorhandene Nachkommastellen abschneiden kann so dass ich einen Integer bekomme?

DaCoda 26. Mai 2024 18:12

AW: Nachkommastellen von Extended abschneiden um Integer zu erhalten
 
Also bei mir ergibt 24.1 * 10.0 genau 241

Code:
var iDummy: Integer;

iDummy := (24.1 * 10.0);
Also müsstest du (AIMINGRESULT * 10.0).AsInterger in die Datenbank schreiben.

Kostas 26. Mai 2024 18:36

AW: Nachkommastellen von Extended abschneiden um Integer zu erhalten
 
ja, bei mir auch wenn ich es so teste.

Die 24.1 werden aus mehreren Werten zusammen addiert und genau das führ zu diesem Seiteneffekt.
Es hängt damit zusammen wie Float Werte verarbeitet werden.

Code:
var a,b,c:extended;
begin
  inherited;
  a := 8.0;
  b := 8.4;
  c := a + b + 7.7;
  ShowMessage(Trunc(c * 10).ToString);


[Edit] ich könnte für meinen Fall anstelle von extended auch real verwenden. Dann würde zumindest dieser Fall funktionieren aber es muss doch eine zuverlässige Lösung dafür geben oder?

[Edit2]
Code:

var a,b,c,d,e:extended;
    i:integer;
begin
  inherited;
  a := 8.0;
  b := 8.4;
  c := 7.7;
  d := a + b + c;
  e := d * 10.0; // hier ist der Wert immer noch richtig e=241.
  i := Trunc(e); //Trunc schneidet nicht ab sondern Rundet oder konvertiert.
  ShowMessage(i.ToString);

DaCoda 26. Mai 2024 19:01

AW: Nachkommastellen von Extended abschneiden um Integer zu erhalten
 
Bei mir geht das, wenn man das TRUC weg lässt:
Code:
var a,b,c:extended;
begin
  a := 8.0;
  b := 8.4;
  c := a + b + 7.7;
  ShowMessage((c * 10.0).ToString);    // <-- Ergibt bei mir 241;
end;

Kostas 26. Mai 2024 19:43

AW: Nachkommastellen von Extended abschneiden um Integer zu erhalten
 
es könnten eben Nachkommastellen entstehen je nachdem was addiert wird. Ich benötige nach der Addition NUR die vor Kommastellen abgeschnitten nicht gerundet.

Michael II 26. Mai 2024 23:42

AW: Nachkommastellen von Extended abschneiden um Integer zu erhalten
 
Du schreibst du willst nicht runden. Darum kommst du nicht rum, wenn du mit trunc arbeitest. trunc rundet immer gegen 0: Wenn der in e:extended gespeicherte Wert zwar nahe einer integer Zahl i liegt, aber etwas unter i, dann liefert trunc(e) den Wert i-1 zurück.
Du schreibst weiter oben im Code // e := d * 10.0; // hier ist der Wert immer noch richtig e=241. - Das stimmt nicht; da "betrügt" dich die IDE.
Fall A: In e.frac ist nach e := d * 10.0;
1111000011111111111111111111111111111111111111111111111111 111111 gespeichert (gespeicherter Wert in e 240.höchstdarstellbare Nachkommazahl)
Fall B: Wohingegen nach e := 241; in e.frac
1111000100000000000000000000000000000000000000000000000000 000000
gespeichert ist - also genau 241.

Da trunc gegen 0 rundet, wird im Fall A 240 (11110000) ausgegeben, im Fall B 241 (11110001).

Es gibt diverse Möglichkeiten, das Problem zu lösen (und viele Beiträge dazu in DP).

Data.FmtBcd
Currency (Im "Mischbetrieb" mit extended und Co treten natürlich ähnliche Probleme auf)
Daran denken, dass extended unter Win32 genauer ist als unter Win64 (extended=double) und damit nicht die gleichen "Rundungsprobleme" aftreten.
setroundmode - Rundungsverhalten der FPU steuern - zum Beispiel: setroundmode( rmUp );

Uwe Raabe 27. Mai 2024 09:59

AW: Nachkommastellen von Extended abschneiden um Integer zu erhalten
 
Das gemeine darin ist auch, dass diese Problematik an unterschiedlichen Stellen im Zahlenraum auftritt, je nachdem ob man mit Single, Double oder Extended arbeitet.

Kostas 27. Mai 2024 12:21

AW: Nachkommastellen von Extended abschneiden um Integer zu erhalten
 
Eine Möglichkeit wäre, in String zu konvertieren, nach dem Komma abscheiden und wieder ein Integer daraus machen, das das ist doch sicherlich nicht dir Lösung.
In diesem speziellen Fall kann ich zuverlässig sagen, ich habe zwei Stellen. Für die eine habe ich immer zuverlässig eine Nachkommastelle und für den anderen Fall haben ich zuverlässig immer nur zwei Nachkommastellen. Der Bereich geht von 0.0 bis 799.9 oder 0.0 bis 799.99

Amateurprofi 27. Mai 2024 15:21

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

Zitat von Kostas (Beitrag 1537154)
Hat jemand eine Idee ich ich zuverlässig aus einem Extended mit 10 multiplizieren kann und danach evl. vorhandene Nachkommastellen abschneiden kann so dass ich einen Integer bekomme?

Delphi-Quellcode:
So vielleicht?
var
   Value:Extended;
   IntValue:Integer;
Value:=24.1 * 10;
IntValue:=Trunc(Value+0.5);

himitsu 27. Mai 2024 15:25

AW: Nachkommastellen von Extended abschneiden um Integer zu erhalten
 
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 ...


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:33 Uhr.
Seite 1 von 3  1 23      

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