![]() |
Nachkommastellen abschneiden OHNE Runden ??
Bin echt am Verzweifeln:
Ich habe einen Rechenwert (Float), z.B. 0.987, und jetzt will ich den Wert auf 2 Nachkommastellen einfach abschneiden, also 0.98 ,ohne Runden. Habe schon probiert mit
Delphi-Quellcode:
usw. aber der rundet immer.
FloattoStrF
Wie geht das richtig? Danke! |
Re: Nachkommastellen abschneiden OHNE Runden ??
Delphi-Quellcode:
NeueZahl := trunc(Zahl * 100) / 100;
|
Re: Nachkommastellen abschneiden OHNE Runden ??
Zitat:
|
Re: Nachkommastellen abschneiden OHNE Runden ??
Zitat:
Beweis:
Delphi-Quellcode:
:shock:
program FloatingPointTuecken;
{$APPTYPE CONSOLE} uses SysUtils; Var i : Integer; Beispiel, Abgerundet : Double; Function Abrunden (Zahl : Double) : Double; Begin Result := Trunc (Zahl * 100) / 100; End; begin for i:=1 to maxint do begin Beispiel := i/100; // Klar, eine Zahlen auf 2 Stellen Abgerundet := Abrunden(Beispiel); // Sicherheitshalber abrunden if Abs (Beispiel - Abgerundet)>0.005 Then // Falls das nicht klappt, ... writeln(i,Beispiel,Abgerundet); // wundern! end; end. Abhilfe: Berücksichtigen der Rundungsfehler, indem wir 'fast aufrunden':
Delphi-Quellcode:
Hier der komplette Testcode: Er testet alle Zahlen -maxint/100 .. +maxint/100;
function KorrektesAbrunden(Zahl: Double): Double;
Const KorrekturDerSchutzStellen = 0.5 - 1E-16; begin If Zahl < 0 then Result := Trunc(Zahl * 100 - KorrekturDerSchutzStellen) / 100 Else Result := Trunc(Zahl * 100 + KorrekturDerSchutzStellen) / 100; end;
Delphi-Quellcode:
program FloatingPointTuecken;
{$APPTYPE CONSOLE} uses SysUtils; type TAbrundenFunktion = function(Zahl: Double): Double; function Abrunden(Zahl: Double): Double; begin Result := Trunc(Zahl * 100) / 100; end; function KorrektesAbrunden(Zahl: Double): Double; Const KorrekturDerSchutzStellen = 0.5 - 1E-16; begin If Zahl < 0 then Result := Trunc(Zahl * 100 - KorrekturDerSchutzStellen) / 100 Else Result := Trunc(Zahl * 100 + KorrekturDerSchutzStellen) / 100; end; function ZahlenUngleich(Zahl1, Zahl2: Double): Boolean; begin Result := Abs(Zahl1 - Zahl2) > 0.005; end; procedure ZeigeFehler(Funktionsname : String; Zahl, Gerundet: Double); begin Writeln('Die Funktion "',Funktionsname,'" funktioniert nicht korrekt.'); Writeln('Beispiel:'); Writeln(' Zahl : ', Zahl: 8: 2); Writeln(' Abgerundet : ', Gerundet: 8: 2); Writeln; end; procedure TesteKorrektesRundenMit(FunktionsName : String; EineAbrundenFunktion: TAbrundenFunktion); var i: Integer; Beispiel, Abgerundet : Double; begin for i := -maxint to maxint do begin Beispiel := i / 100; Abgerundet := EineAbrundenFunktion(Beispiel); if ZahlenUngleich(Beispiel, Abgerundet) then begin ZeigeFehler(Funktionsname, Beispiel, Abgerundet); Exit; end; end; Writeln('Die Funktion "',Funktionsname,'" funktioniert besser'); end; begin TesteKorrektesRundenMit('Gängige Version', Abrunden); TesteKorrektesRundenMit('Korrigierte Version', KorrektesAbrunden); ReadLn; end. |
Re: Nachkommastellen abschneiden OHNE Runden ??
Das passiert aber nur wenn "NeueZahl" keine Ganzzahl (Integer, Word, Byte etc.) ist oder?
|
Re: Nachkommastellen abschneiden OHNE Runden ??
Zitat:
Aber da ganze Zahlen als Floating Point exkat darstellbar sind, dürfte das ok sein. |
Re: Nachkommastellen abschneiden OHNE Runden ??
Zitat:
Ein Int64 (dessen Wertebereich) ist in einem Extended darstellbar, aber nicht in einem Single. |
Re: Nachkommastellen abschneiden OHNE Runden ??
Zitat:
Ganze Zahlen sind ja nicht nur Integer, Int64 usw. Auch eine Zahl vom Typ Extended kann eine ganze Zahl sein, z.B. "1.0" :shock: Aber es ist ja klar, das wir "kaputte bzw. ganze Zahlen" im Kontext des Wertebereichs des Floating-Point Datentyps meinen. [klugscheissmodus=aus] |
Re: Nachkommastellen abschneiden OHNE Runden ??
18.446.744.073.709.551.616 ist 'ne Ganzzahl und ein Single kann diese zufällig ganz genau darstellen.
18.446.744.073.709.551.615 ist auch eine Ganzzahl und paßt sogar in den Wertebereichs des Single, aber eben nicht ganz genau, da für den Single quasi all diese Ganzzahlen 18.446.744.xxx.xxx.xxx.xxx das Selbe sind. |
Re: Nachkommastellen abschneiden OHNE Runden ??
Du hast vergessen, den KS-Modus einzuschalten. :roll: Worauf willst du denn hinaus?
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:39 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