Autor Beitrag
Martin13
Hält's aus hier
Beiträge: 9



BeitragVerfasst: Sa 13.11.04 23:53 
Ich möchte in einem Script mit Brüchen rechen aber irgendwie gibts damit Probleme...
Mein Problem wird am folgendem Beispiel deutlich:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
a:=100;
b:=1/10;
if b - 0.1 = 0 then begin
a:=99 end;


obwohl die if-Bedingung eigentlich erfüllt ist, ist a bei mir immer 100...
Kann mir da jemand was hilfreiches zu sagen?!?

Moderiert von user profile iconChristian S.: Delphi-Tags hinzugefügt.
wulfskin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1349
Erhaltene Danke: 1

Win XP
D5 Pers (SSL), D2005 Pro, C, C#
BeitragVerfasst: So 14.11.04 00:04 
Ich denke, wenn die Variablen a und b vom Typ Extended sind, solltest du keine Probleme damit haben!

Gruß Hape!

_________________
Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
Martin13 Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: So 14.11.04 00:05 
habe ich auch gedacht... ;-)
Kroni
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 720

Win 98, Win ME, Win2k, Win XP
D3 Pro
BeitragVerfasst: So 14.11.04 01:18 
welche rechenart willste denn mit dem Code machen?
Ich nehme an, dass du mit dem
ausblenden Delphi-Quelltext
1:
2:
if (b-0.1)=0 then
bla

testen willst, ob der Bruch nun 1/10 oder so ist, oder sehe ich das falsch?
Versuchs mal mit einer Klammer um das b-0.1....das bewirkt auch oft wunder=)
ansonsten, was soll das programm insgesamt machen...Brüche addieren, subtrahieren multiplizieren und divideiren oder wie?
wenn das diese Rechenarten beherrschen soll, würd ich dir Empfehlen, das ganze ganz anders zu behandeln.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 14.11.04 01:26 
Wo ist Chef's Signatur, wenn man mal drauf verweisen muss :(

Keine Vergleiche mit Istgleich bei Gleitkommazahlen!

Richtig wäre

ausblenden Delphi-Quelltext
1:
If Abs(B - 0.1) < 1E-12 Then					

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Kroni
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 720

Win 98, Win ME, Win2k, Win XP
D3 Pro
BeitragVerfasst: So 14.11.04 01:29 
*Mal eben das Programm geteste habe*
Bei mir hat er 99 angezeigt.....aber ok, hast schon recht BenBE....klingt schon logisch, was du da schreibst *nicht ironisch*
Martin13 Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: So 14.11.04 03:19 
Erst mal Dankeschön für alle bereits gegeben Antworten!

Mein eingentlcihes Ziel ist es für eine Dezimalzahl zwischen 0 und 0,5 einen Bruch zu feinden, bei dem im Zähler eine 1 steht und bei dem die Abweichung möglichst klein ist....

Ich habe das daher so geschrieben:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
inde:=1;
while rest-(1/inde) < 0 do begin
inde:=inde+1;
end;


wenn jetzt "rest" zum Beispiel 0,1 ist, hatte ich erwartet, dass als Ergebniss für inde 10 herauskommt, stattdessen kam 11 herraus. Das habe ich erstmal so hingenommen und den Script noch um das erweitert:
ausblenden Delphi-Quelltext
1:
2:
if (1/(inde-1))<>rest then begin
...


Ich hatte gehofft, das der Script hier die 11 auf 10 veringert und dann abbricht weil 10/1 und 0.1 nicht ungleich sind... Leider hat das auch nicht geklappt...
Ich wäre also dankbar, wenn mir noch einer erklären könnte was BenBE meint, wenn er sagt, dass man bei Gleitkommazahlen keine Vergaeiche anstellen soll, und vor allem, wie muss ich meinen Script umschreiben?


Zuletzt bearbeitet von Martin13 am So 14.11.04 13:21, insgesamt 1-mal bearbeitet
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 14.11.04 03:34 
Für Ungleich:

ausblenden Delphi-Quelltext
1:
If Abs(A-B) > 1E-12 Then					


Du kannst aber für dein Problem mal folgenden Source probieren:

ausblenden Delphi-Quelltext
1:
2:
inde:=1;
while Abs(rest-1/inde) < 1E-12 do inde:=inde+1;


P.S.: Bitte nutze die Delphi-Tags für Quelltextabschnitte.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8535
Erhaltene Danke: 473

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: So 14.11.04 12:11 
zu den Gleitkommazahlen:
Das Problem liegt daran, dass im Rechner die Zahlen im Binärsystem gespeichert sind. Außerdem steht zur Speicherung einer Zahl nur begrenzt viel Platz zur Verfügung. Oftmals ist es so, dass einfache Dezimalzahlen sich binär nicht exakt darstellen lassen. Versuch mal, durch Addition von 2erPotenzen (1/2, 1/4, 1/8, 1/16, 1/32,..) den Wert 1/10 zu erhalten - es geht nicht.
Also muss der Rechner runden. Und weil es schwierig zu sagen ist, wie nun genau gerundet wird, oder wie sich diverse Rundungsfehler addieren oder gegenseitig auslöschen, sollte man bei Gleitkommazahlen niemals testen, ob sie gleich sind, sondern nur, ob sie fast gleich sind.

für dein Problem:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
minabstand:=2;
mingefunden:=FALSE;
i:=0;
repeat
    inc(i);
    tmpabstand:=abs(zahl-1/i);
    if tmpabstand < minabstand then minabstand:=tmpabstand;
    if tmpabstand >= minabstand then mingefunden:=TRUE;    
until mingefunden;


Erläuterung: gehe alle Zahlen 1/1, 1/2, 1/3, 1/4, etc durch und bestimme den Abstand zu deiner Zahl, die du näherungsweise durch 1/x darstellen willst.
Wenn der Abstand kleiner geworden ist, hast du eine bessere Näherung gefunden, und du solltest noch weiter suchen. Ist der ABstand größer als der beste gefundene, dann bist du "über deine Zahl hinausgelaufen", und entfernst dich wieder von ihr. Man kann also abbrechen.

EDIT:
- Code korrigiert
- Anmerkung zu den anderen Codes: Schon mal was von Endlosschleifen gehört? :roll:

_________________
We are, we were and will not be.
Martin13 Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: So 14.11.04 13:55 
erstmal nochmal ein Dank für die aufschlussreichen antworten, doch leider bekomme ich bei beiden Scriptvorschlägen für inde bzw. i immer eine 1 als Ergebniss!?!
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8535
Erhaltene Danke: 473

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: So 14.11.04 14:38 
Aaaaarrgggghhhh :autsch:
Dummer Fehler von mir. So gehts.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
minabstand:=2;
mingefunden:=FALSE;
i:=0;
zahl:=0.1;
repeat
  inc(i);
  tmpabstand:=abs(1/i-zahl);
  if tmpabstand < minabstand then minabstand:=tmpabstand
  else  mingefunden:=TRUE; // Das andere war Quatsch, weil die Bedingung immer erfüllt war
until mingefunden;
dec(i); // eins wieder zurück

_________________
We are, we were and will not be.
Martin13 Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: So 14.11.04 15:01 
habe gerade den logigfehler in Gausis Scrpt bemerkt, deswegen kam immer eine 1 für i heraus. (Die Zeieln 7 und 8 müssen vertauscht werden oder in Zeile 8 muss die erneute if bedingung durch ein else ersetzt werden...)

Habe das jetzt gerade bei mir korrigiert, aber jetzt kommt bei zahl=10 für i wieder 11 herraus obwohl ich eine 10 brauche...

Bei der Variante von BenBE kam zunächst auch immer nur eine 1, bis ich mal die abs() Funktion weggelassenhabe und jetzt kommt wieder eine 11 herraus...

Ich bin also mehr oder weniger wieder am Anfang... :-(

Hat jemand noch eine Idee wie man das Problem lösen kann?!?

EDIT: Oups.. Sorry, ich sehe gerade Gausi hat den Fehler schon vorher bemerkt...
EDIT2: Gausis neue Variante funktioniert!
Dank an Gausi!