Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   gerundete Zahlen werden nicht weiterverarbeitet (https://www.delphipraxis.net/170932-gerundete-zahlen-werden-nicht-weiterverarbeitet.html)

vitapower 10. Okt 2012 22:44

gerundete Zahlen werden nicht weiterverarbeitet
 
Hallo,

habe folgendes Problem.

es werden zwei Zahlen im Edit eingegeben, die werden halbiert und auf zwei Kommastellen gerundet.
Dann folgt eine IF Anweisung, die nicht so richtig funktioniert.


var x,y:real;
r2:=RoundTo(x / y,-2);
IF R2 =0.49 THEN BEGIN Faktor1:=2.168 END;
IF R2 =0.50 THEN BEGIN Faktor1:=2.1861 END;
IF R2 =0.51 THEN BEGIN Faktor1:=2.2041 END;


Also bei r2=0,5 zeigt mir Label den richtigen Faktor1, bei den anderen nicht.

HAt jemmand eine Idee was falsch sein könnte. Ich vermute, dass abgerundete Zahl im "System" noch komplett besteht und daher erkennt IF die nicht. Aber wie macht man es besser?

Bummi 10. Okt 2012 22:49

AW: gerundete Zahlen werden nicht weiterverarbeitet
 
Delphi-Quellcode:
r2:Integer

r2:=Round(100 * x / y);
IF R2 =49 THEN BEGIN Faktor1:=2.168 END;
IF R2 =50 THEN BEGIN Faktor1:=2.1861 END;
IF R2 =51 THEN BEGIN Faktor1:=2.2041 END;


//oder
Case R2 of
   49:Faktor:=2.168;
   50:Faktor:=2.1861;
// etc.
end;

Amateurprofi 10. Okt 2012 23:17

AW: gerundete Zahlen werden nicht weiterverarbeitet
 
Zitat:

Zitat von vitapower (Beitrag 1186588)
Hallo,

habe folgendes Problem.

es werden zwei Zahlen im Edit eingegeben, die werden halbiert und auf zwei Kommastellen gerundet.
Dann folgt eine IF Anweisung, die nicht so richtig funktioniert.


var x,y:real;
r2:=RoundTo(x / y,-2);
IF R2 =0.49 THEN BEGIN Faktor1:=2.168 END;
IF R2 =0.50 THEN BEGIN Faktor1:=2.1861 END;
IF R2 =0.51 THEN BEGIN Faktor1:=2.2041 END;


Also bei r2=0,5 zeigt mir Label den richtigen Faktor1, bei den anderen nicht.

HAt jemmand eine Idee was falsch sein könnte. Ich vermute, dass abgerundete Zahl im "System" noch komplett besteht und daher erkennt IF die nicht. Aber wie macht man es besser?

Falsch ist deine Vorstellung von der Vergleichbarkeit von Dezimalbrüchen.

Abgesehen von Potenzen von 2 können Dezimalbrüche bei Realzahlen nicht exakt dargestellt werden.

Sei x=49 und y=100 dann wird nach r2:=RoundTo(x / y,-2) r2 zwar einen Wert haben, der nahe bei 0.49 liegt, aber eben nicht exakt.

Der Vergleich wird über die FPU durchgeführt und in der sehen die Zahlen so aus
r2 = 3FFD FAE1 47AE 147A E147
0.49 = 3FFD FAE1 47AE 147A E148
Beachte die letzte Ziffer in beiden Werten.
Abhilfe:
Entweder
if SameValue(0.49,r2) then …

oder
du definierst r2 als integer, rechnest r2:=Round(x*100/y) und testest mit
if r2=49 then …

Lemmy 11. Okt 2012 05:50

AW: gerundete Zahlen werden nicht weiterverarbeitet
 
oder du verwendest für R2 den Typ Currency (letzlich ein verkappter Int64).

vitapower 11. Okt 2012 06:46

AW: gerundete Zahlen werden nicht weiterverarbeitet
 
Danke für schnelle und ausführliche Antworten, werde heute nach der Arbeit testen.

Caps 11. Okt 2012 12:19

AW: gerundete Zahlen werden nicht weiterverarbeitet
 
Man kann die "Gleichheit" von zwei Real-Zahlen auch so testen:

Delphi-Quellcode:
var
   a, b // die zu vergleichenden Werte
   epsilon: Real;

epsilon := 1e-8; // irgendeine Genauigkeit (hier 10^-8)

if abs(a-b) < epsilon then showmessage('a und b sind gleichgroß');
Gruß

himitsu 11. Okt 2012 13:16

AW: gerundete Zahlen werden nicht weiterverarbeitet
 
Statt dem manuellen Vergleich, kann man auch gleich die passenden Funktionen nutzen, da sieht man dann eher, was gemacht wird.
Delphi-Referenz durchsuchenIsZero Delphi-Referenz durchsuchenSameValue Delphi-Referenz durchsuchenCompareValue Delphi-Referenz durchsuchenSign Delphi-Referenz durchsuchenInRange

zu IsZero:
0 ist zwar einer der wenigen Werte, welche man theoretisch direkt vergleichen könnte, aber wenn die 0 das Ergebnis einer Berechnung ist, dann muß es ja nicht ganz genau 0 sein.
z.B.: 18 - fast genau 18 = nur fast 0

Furtbichler 11. Okt 2012 16:44

AW: gerundete Zahlen werden nicht weiterverarbeitet
 
Zitat:

Zitat von Caps (Beitrag 1186643)
Man kann die "Gleichheit" von zwei Real-Zahlen auch so testen:

Delphi-Quellcode:
var
   a, b // die zu vergleichenden Werte
   epsilon: Real;

epsilon := 1e-8; // irgendeine Genauigkeit (hier 10^-8)

if abs(a-b) < epsilon then showmessage('a und b sind gleichgroß');
Gruß

Genau um so etwas nicht per Hand zu programmieren, sind die von himitsu aufgelisteten Funktionen da. Denn diese 'irgendeine Genauigkeit' ist nicht so einfach vorzugeben. Wenn Du im Nanometerbereich arbeitest, dann ist dein epsilon viel zu groß, bei Lichtjahren allerdings viel zu klein (Basiseinheit Meter).

Da ist 'SameValue' mit dem defaultwert 'epsilon=0' schon pfiffiger. Schau Dir mal den Quelltext an.

vitapower 11. Okt 2012 19:20

AW: gerundete Zahlen werden nicht weiterverarbeitet
 
Habe mit integer gelöst, war die einfachste Lösung.
Vielen Dank an alle!!!!!


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:09 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