Abfrage: Nachkommastellen

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Kosmo
Beiträge: 15
Registriert: Di 23. Nov 2010, 18:06

Abfrage: Nachkommastellen

Beitrag von Kosmo »

Sehr geerte Leser,

ich habe ein kleines Problem und zwar weiß ich nicht, wie man überprüfen kann, ob eine Zahl Nachkommastellen besitzt, also nach dem Komma noch etwas kommt, oder mit 0 nach dem Komma endet, also ob eine Zahl so aussieht (x.54673...) oder so(x.0)

Ich hoffe ihr könnt mir helfen

Mit freundlichen Grüßen
Kosmo

marcov
Beiträge: 1102
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Abfrage: Nachkommastellen

Beitrag von marcov »

Code: Alles auswählen

hatnumericchars:=false;
if length(x)>n and (s[n]='.') then  // position n hat ein punkt
  begin
    n:=n+1;
    alten:=n;
    while (n<length(x)) and (s[n] in ['0'..'9'] do inc(n);
    hatnumericchars:=n<>alten;
  end;

Kosmo
Beiträge: 15
Registriert: Di 23. Nov 2010, 18:06

Re: Abfrage: Nachkommastellen

Beitrag von Kosmo »

Danke für deine Hilfe, aber ich weiß nicht richtig wie ich das umsetzen soll.

Code: Alles auswählen

var anfang,ende,n:integer;
var ergebnis1,ergebnis2,ergebnis3:real;
begin
listbox1.clear;
anfang:=StrToInt(edit1.Text);
ende:=StrToInt(edit2.Text);
n:=anfang;
for anfang:=StrToInt(edit1.Text) to ende do begin
ergebnis1:=anfang*anfang*2+1;
ergebnis2:=sqrt(ergebnis1);
ergebnis3:=anfang*anfang;
listbox1.Items.Add(IntToStr(n)+' - '+FloatToStr(ergebnis1)+' - '+FloatToStr(ergebnis2)+' - ' +FloatToStr(ergebnis3)); // nur wenn ergebnis2 eine nat. Zahl ist
n:=n+1;
end;
end;
Also das ist der Programmtext und ich will halt, dass nur die Ergebnisse in die Listbox eingetragen werden, bei denen das Ergebnis2 eine nat. Zahl ist. Also wie soll ich das genau dann machen.

Ich hoffe ihr könnt mir helfen.
Zuletzt geändert von Lori am Fr 7. Jan 2011, 22:04, insgesamt 1-mal geändert.
Grund: Highlighter

Kosmo
Beiträge: 15
Registriert: Di 23. Nov 2010, 18:06

Re: Abfrage: Nachkommastellen

Beitrag von Kosmo »

Danke für die Hilfe, habe aber nun eine ganz leichte Möglichkeit gefunden. :)

Code: Alles auswählen

rErgebnis2:= round(ergebnis2);
if(ergebnis2=rErgebnis2) then begin


Also nochmals vielen Dank
Zuletzt geändert von Lori am Fr 7. Jan 2011, 22:04, insgesamt 1-mal geändert.
Grund: Highlighter

carli
Beiträge: 657
Registriert: Sa 9. Jan 2010, 17:32
OS, Lazarus, FPC: Linux 2.6.x, SVN-Lazarus, FPC 2.4.0-2
CPU-Target: 64Bit

Re: Abfrage: Nachkommastellen

Beitrag von carli »

Es kann sein, dass deine Methode nur geht, wenn du mit den Fließkommazahlen nicht rechnest (vor allem nicht addieren, quadrieren oder gar Wurzel ziehen)

Du solltest beim Vergleichen immer gegen einen Toleranzwert vergleichen (z.B. 0.00001), da der Computer gerne mal in die falsche Richtung rundet.

Socke
Lazarusforum e. V.
Beiträge: 3177
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Abfrage: Nachkommastellen

Beitrag von Socke »

carli hat geschrieben:Es kann sein, dass deine Methode nur geht, wenn du mit den Fließkommazahlen nicht rechnest (vor allem nicht addieren, quadrieren oder gar Wurzel ziehen)

Du solltest beim Vergleichen immer gegen einen Toleranzwert vergleichen (z.B. 0.00001), da der Computer gerne mal in die falsche Richtung rundet.
Man kann sich mit trunc() auch nur den Ganzzahlwert (ohne Dezimalstellen) holen. Wird manchmal auch Abrunden genannt.
Bei round() gehts um die nächstliegende Integerzahl. Maßgeblich dürfte die binäre Repräsentation der Fließkomma zahl sein (etwas anderes wäre nach meinem Verständnis auch nicht sinnvoll).
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

am2
Lazarusforum e. V.
Beiträge: 116
Registriert: Di 21. Dez 2010, 09:59
OS, Lazarus, FPC: Win (L 0.9.26 beta FPC 2.2.2)
CPU-Target: 32 Bit

Re: Abfrage: Nachkommastellen

Beitrag von am2 »

Kosmo hat geschrieben:Danke für deine Hilfe, aber ich weiß nicht richtig wie ich das umsetzen soll.

Code: Alles auswählen

var anfang,ende,n:integer;
var ergebnis1,ergebnis2,ergebnis3:real;
begin
listbox1.clear;
anfang:=StrToInt(edit1.Text);
ende:=StrToInt(edit2.Text);
n:=anfang;
for anfang:=StrToInt(edit1.Text) to ende do begin
ergebnis1:=anfang*anfang*2+1;
ergebnis2:=sqrt(ergebnis1);
ergebnis3:=anfang*anfang;
listbox1.Items.Add(IntToStr(n)+' - '+FloatToStr(ergebnis1)+' - '+FloatToStr(ergebnis2)+' - ' +FloatToStr(ergebnis3)); // nur wenn ergebnis2 eine nat. Zahl ist
n:=n+1;
end;
end;
Also das ist der Programmtext und ich will halt, dass nur die Ergebnisse in die Listbox eingetragen werden, bei denen das Ergebnis2 eine nat. Zahl ist. Also wie soll ich das genau dann machen.

Ich hoffe ihr könnt mir helfen.
Also ich tippe mal ganz stark auf eine Schulaufgabe. Daher möchte ich Dir lieber Hilfe zur Selbsthilfe leisten, als eine Lösung für Dein konkretes Problem.

1. Du kannst Gleitkommazahlen nicht auf Gleichheit testen, auch wenn es scheinbar unproblematisch ist. Selbst, wenn eine Anzeige eine natürliche Zahl liefert, dann kann es sein, dass irgendwo eine Nachkommastelle existiert, die Du nicht siehst, weil eine Zahl intern im Binärsystem dargestellt wird. Wenn Dein Lehrer es so halbwegs korrekt macht, dann dürfte er Deine Lösung nicht ohne Abzug akzeptieren. Bei Gleitkommazahlen solltest Du grundsätzlich die Differenz oder den Quotienten gegen ein genügend kleines Epsilon prüfen.
So, wie Socke schon schreibt: die interne Repräsentation als Gleitkommazahl ist relevant. Es nützt Dir u.U. nichts, wenn Du rundest oder Trunc benutzt, es sei denn Du schreibst das Ergebnis wirklich in eine Festkommazahl (z.B. integer). Es könnte schon problematisch sein, wenn die zu vergleichenden Zahlen vom unterschiedlichen Typ sind (extended und double oder so)
2. Strukturiere Deinen Quelltext, das erspart Dir Überraschungen. Wenn Du irgendwo eine Zeile gestrichen hast, passiert es leicht, dass die Struktur nicht mehr stimmt. So hast Du Schwierigkeiten, das zu bemerken.
3. Achte auf Deine Variablen.
- Du initialisierst Anfang 2 mal (nicht schlimm, aber unnötig)
- Du verwendest n, obwohl Du in Anfang - zumindest so, wie es hier steht - den gleichen Wert hast (nicht schlimm, solange Du nicht vergißt, n hochzuzählen, bleibt aber unnötig)

Wenn Du wissen willst, ob eine berechnete Zahl eine natürliche Zahl ist, dann könntest Du beispielsweise diese in eine Zeichenkette umzuwandeln und nach Nachkommastellen suchen. Oder Du bildest die Differenz zwischen dem ermittelten und dem gerundeten Wert und prüfst, ob das unterhalb eines Toleranzwertes ist. Aber: Je größer die Zahl, desto größer das Risiko. Frage: Ist 15241383937 eine Quadratzahl?

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Abfrage: Nachkommastellen

Beitrag von mschnell »

Kosmo hat geschrieben:ob eine Zahl Nachkommastellen besitzt
Das Problem gibt es "offiziell" gar nicht. Eine Real-Zahl ist immer nur "im Rahmen der Genauigkeit" definiert. Die Genauigkeit ist Implementierungs- und möglicherweise Hardware- abhängig und die Zahl-Darstellung ebenfalls. Es kann also theoretisch sein, dass ein Rechen-Ergebnis auf einem Rechner 100 und auf einem anderen Rechner 100.000000000000000000001 ist. Da darfst Du dich nicht drauf verlassen.

-Michael

Antworten