[gelöst]Variablentyp für Nachkommastellen/Pi-Berechnung
Re: Variablentyp für lange Nachkommastellen (Pi-Berechnung)
Hallo,
da steht exp(x*ln(2)) => 2^x
Gruß Horst
da steht exp(x*ln(2)) => 2^x
Gruß Horst
Re: Variablentyp für lange Nachkommastellen (Pi-Berechnung)
Mann, warum geben die Leute hier so schnell auf?^^ok das einbinden hat geklappt aber bigdecimal haut mit einer fehlermeldung raus das (die wurzel aus 2) keine zahl sei.... ich werd es wohl mit gmp machen
Die BigDecimal Routinen nehmen an, dass der Dezimaltrenner ein Punkt ist - im deutschen Windows ist das aber das Komma. Füge "SysUtils" zur "Uses"-Liste hinzu und setze an den Anfang deines Codes:
Code: Alles auswählen
uses
..., SysUtils, ...;
begin
DefaultFormatSettings.DecimalSeparator := '.';
...
-
- 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: Variablentyp für lange Nachkommastellen (Pi-Berechnung)
Nö. So geht's:heheracer hat geschrieben:deklariere die variablen als mpf_t,
Code: Alles auswählen
var
r1, r2, r3: MPFloat;
s: String;
procedure TForm1.FormCreate(Sender: TObject);
begin
f_set_str(r1, '1.0', 10); // r1 := 1.0;
f_set_str(r2, '2.0', 10); // r2 := 2.0;
r3 := r1+r2;
s := r3;
caption := s;
end;
-
- 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: Variablentyp für lange Nachkommastellen (Pi-Berechnung)
Die braucht man zur Berechnung von Pi nicht.indianer-frank hat geschrieben:GMP hat keine Fließkommafunktionen (exp, ln, sin, power, etc.) wie in Deinem Code. Wenn Du sowas brauchst
Wenn man sie für andere Zwecke braucht, kann man sie in Pascal mit normalen Arithmetischen Funktionen aufbauen. Mathematische Literatur dazu gibt es genug.
Bei Normaler Arithmetik werden hier Tabellen verwendet. Das geht bei beliebig hoher Genauigkeit natürlich nicht, weil die Tabellen ja in der entsprechenden Genauigkeit vorliegen müssen.
-Michael
Re: Variablentyp für lange Nachkommastellen (Pi-Berechnung)
Um es mir "einfacher" zu machen hab ich mal ein konsolenprogramm geschrieben und mparith benutzt.
Die uses Klausel ist so voll, da ich zu faul war zu gucken welche units wirklich benutzt werden und welche nicht.
Nachdem ich mich nun erstmal von gmp verabschiedet habe (totaler murks, es gibts 3 variablen typen mpfloat, mpf_t und mp_float und für jeden befehl braucht man einen anderen typ...) wollte ich mein Glück mit MPArith probieren.
Die Befehle sind etwas seltsam (wenn man a/b machen will etwa muss man mpf_dec(a,b,c) machen) aber ich hab mich schon gefreut als das kompilieren ohne Error verlief. Programm starten, erstmal 1 eingeben und...
eine Fehlermeldung bekommen -.-
Exception-Klasse >>MPCNotInit<< Meldung: mp_set
Datei mp_base.pas Zeile 7725:
Und hab leider nicht die geringste Ahnung wieso das nicht funktioniert.
MfG
PS: Ich vergesse es viel zu häufig: Danke an alle! Der Informatikunterricht in der Schule ist sehr sehr langsam und ich hab hier schon (u. a. dank eurer Hilfe) schon viel dazu gelernt.
Code: Alles auswählen
program pi2;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes, sysutils, btypes, hrtimer, isaac, mp_base, mp_calc, mp_cmplx,
mp_modul, mp_numth, mp_pfu, mp_prime, mp_prng, mp_ratio, mp_rc16, mp_rc32,
mp_rcalc, mp_real, mp_rsa, mp_supp, mp_types, pfdu, pfdu_crt, taus88, tsc
{ you can add units after this };
var
n, s: longint;
x, c: mp_float;
w: word;
begin
mpf_set0(x);
mpf_set0(c);
writeln('Pi');
write('Genauigkeit: '); readln(s);
for n:=1 to s do
begin
mpf_add_int(x,2,c);
mpf_sqrt(x,c);
end;
w:=50;
writeln('Pi berechnet: ', mpf_adecimal_alt(x,w));
writeln('Pi genau: ', pi:0:50);
mpf_div_ext(x,pi,c);
writeln('Differenz: ', mpf_adecimal_alt(c,w));
readln;
end.
Nachdem ich mich nun erstmal von gmp verabschiedet habe (totaler murks, es gibts 3 variablen typen mpfloat, mpf_t und mp_float und für jeden befehl braucht man einen anderen typ...) wollte ich mein Glück mit MPArith probieren.
Die Befehle sind etwas seltsam (wenn man a/b machen will etwa muss man mpf_dec(a,b,c) machen) aber ich hab mich schon gefreut als das kompilieren ohne Error verlief. Programm starten, erstmal 1 eingeben und...
eine Fehlermeldung bekommen -.-
Exception-Klasse >>MPCNotInit<< Meldung: mp_set
Datei mp_base.pas Zeile 7725:
Code: Alles auswählen
raise MPXNotInit.Create('mp_set');
MfG
PS: Ich vergesse es viel zu häufig: Danke an alle! Der Informatikunterricht in der Schule ist sehr sehr langsam und ich hab hier schon (u. a. dank eurer Hilfe) schon viel dazu gelernt.
Re: Variablentyp für lange Nachkommastellen (Pi-Berechnung)
Ok, da hast du recht. Aber irgendwie funktioniert das nicht so recht.wp_xyz hat geschrieben:Mann, warum geben die Leute hier so schnell auf?^^ok das einbinden hat geklappt aber bigdecimal haut mit einer fehlermeldung raus das (die wurzel aus 2) keine zahl sei.... ich werd es wohl mit gmp machen
Die BigDecimal Routinen nehmen an, dass der Dezimaltrenner ein Punkt ist - im deutschen Windows ist das aber das Komma. Füge "SysUtils" zur "Uses"-Liste hinzu und setze an den Anfang deines Codes:Code: Alles auswählen
uses ..., SysUtils, ...; begin DefaultFormatSettings.DecimalSeparator := '.'; ...
Code: Alles auswählen
program pi3;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes, sysutils, bigdecimalmath
{ you can add units after this };
var
n, s: longint;
x: bigdecimal;
begin
DefaultFormatSettings.DecimalSeparator := '.';
writeln('Pi');
write('Genauigkeit: '); readln(s);
s:=s-1;
x:=0;
for n:=1 to s do
begin
x:=sqrt(2+x);
end;
s:=s+1;
x:=exp(s*ln(2))*sqrt(2-x);
writeln('Pi berechnet: ', bigdecimaltostr(x));
writeln('Pi genau: ', pi:0:50);
//writeln('Differenz: ', bigdecimaltoextended(x/pi*100):0:2, '%'); Stimmt nicht
readln;
end.
1: 1,4
2: 3,06
5: 2,45
10: 0,31
15: 0,02
...
Da ist Extended besser
Edit: Nein ist es nicht... ich hab was falsch gemacht
Edit2: s^2 statt 2^s , mein Fehler. Aber trotzdem, wird es ab 11 Wiederholungen ungenauer statt genauer und ab 27 wird null ausgegeben (Wieso auch immer). Also funktioniert extended doch besser. Bei der Ausgabe ist mir aufgefallen, dass bigdecimal nicht so viele Nachkommastellen hat wie extended. Wie kann man die Nachkommastellenanzahl bei bigdecimal ändern? Vllt geht es dann
MfG
Zuletzt geändert von heheracer am Do 9. Apr 2015, 15:01, insgesamt 3-mal geändert.
Re: Variablentyp für lange Nachkommastellen (Pi-Berechnung)
Das ist auch richtig (Falls du das hinterfragen wolltest).Horst_h hat geschrieben:Hallo,
da steht exp(x*ln(2)) => 2^x
Gruß Horst
Die Formel geht 2^n*Wurzel(2-Wurzel(2+Wurzel(2+Wurzel(2+...)))) mit n Wurzeln.
Deswegen sind die Nachkommastellen so wichtig.
MfG
Re: Variablentyp für lange Nachkommastellen (Pi-Berechnung)
Ich hab es nochmal mit gmp probiert und hab jetzt nur ein kleines Problemchen.
Um von mpfloat die Wurzel zu ziehen benutzt man den Befehl
Eingabe:=2
mpf_sqrt(Eingabe(mpf_t),Ausgabe(mpf_t))
Ausgabe=Wurzel(2)
soweit, so gut
Kompilieren klappt nicht weil:
unit1.pas(64,19) Error: Can't take the address of constant expressions
unit1.pas(67,17) Error: Can't take the address of constant expressions
unit1.pas(76) Fatal: There were 2 errors compiling module, stopping
...
Edit: Ich hab einen kleinen Workaround gemacht, und bin dann da gelandet was mich so "aufregt":
Mit der Fehlermeldung (beim kompilieren):
unit1.pas(65,17) Error: Call by var for arg no. 2 has to match exactly: Got "MPFloat" expected "mpf_t"
MfG
Um von mpfloat die Wurzel zu ziehen benutzt man den Befehl
Eingabe:=2
mpf_sqrt(Eingabe(mpf_t),Ausgabe(mpf_t))
Ausgabe=Wurzel(2)
soweit, so gut
Code: Alles auswählen
label1.caption:='0';
x:=0;
n:=1;
s:=int(strtofloatdef(edit1.text,0));
if s<1 then
begin
s:=1;
showmessage('Ungültige Eingabe');
end;
progressbar1.max:=trunc((s-1)*10);
repeat
n:=n+1;
mpf_sqrt(x,2+x);
progressbar1.stepit;
until n=s;
mpf_sqrt(x,2-x);
x:=exp(s*ln(2))*x;
label1.caption:=floattostr(x);
showmessage('Fertig');
progressbar1.Position:=0;
unit1.pas(64,19) Error: Can't take the address of constant expressions
unit1.pas(67,17) Error: Can't take the address of constant expressions
unit1.pas(76) Fatal: There were 2 errors compiling module, stopping
...
Edit: Ich hab einen kleinen Workaround gemacht, und bin dann da gelandet was mich so "aufregt":
Code: Alles auswählen
c:=2+x;
mpf_sqrt(x,c);
unit1.pas(65,17) Error: Call by var for arg no. 2 has to match exactly: Got "MPFloat" expected "mpf_t"
MfG
-
- 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: Variablentyp für lange Nachkommastellen (Pi-Berechnung)
Eine schöne Art auszudrücken, dass man keine Ahnung hat und auch nichts lernen will !heheracer hat geschrieben:Nachdem ich mich nun erstmal von gmp verabschiedet habe (totaler murks, es gibts 3 variablen typen mpfloat, mpf_t und mp_float und für jeden befehl braucht man einen anderen typ...)
An diesem Punkt sollte dieser Thread abgebrochen werden.
-Michael
Re: Variablentyp für lange Nachkommastellen (Pi-Berechnung)
Naja lernen will ich schon. Aber wenn ich mpf_add machen will und dann mpfloat ausgegeben bekommen und für mpf_sqrt aber mpf_flaot brauche (^^habs nicht mehr so genau im Gedächtnis) dann kann ich mir leider nicht helfen.mschnell hat geschrieben:Eine schöne Art auszudrücken, dass man keine Ahnung hat und auch nicht lernen will !heheracer hat geschrieben:Nachdem ich mich nun erstmal von gmp verabschiedet habe (totaler murks, es gibts 3 variablen typen mpfloat, mpf_t und mp_float und für jeden befehl braucht man einen anderen typ...)
An diesem Punkt sollte dieser Thread abgebrochen werden.
-Michael
Ich sitze an diesem Programm bestimmt schon seit 2 Stunden und probiere alles mögliche aus, lese mir sämtliche Deklarationen durch etc.
Und ich habe nicht gesagt, dass ich nicht gmp benutzen will sondern es erst mal mit MPArith bzw. BigDecimal probieren werde, da mir das auch vorgeschlagen wurde.
Inzwischen versuche ich es nochmal mit gmp
MfG
-
- Beiträge: 134
- Registriert: So 30. Nov 2008, 21:53
Re: Variablentyp für lange Nachkommastellen (Pi-Berechnung)
Du must Deine Variable initialisieren, die Formeln richtig verwenden (siehe x = 2^(s+1)*sqrt)2-x), etc. hier ein lauffähige Version:heheracer hat geschrieben:Um es mir "einfacher" zu machen hab ich mal ein konsolenprogramm geschrieben und mparith benutzt.
eine Fehlermeldung bekommen -.-
Exception-Klasse >>MPCNotInit<< Meldung: mp_set
Datei mp_base.pas Zeile 7725:Und hab leider nicht die geringste Ahnung wieso das nicht funktioniert.Code: Alles auswählen
raise MPXNotInit.Create('mp_set');
MfG
PS: Ich vergesse es viel zu häufig: Danke an alle! Der Informatikunterricht in der Schule ist sehr sehr langsam und ich hab hier schon (u. a. dank eurer Hilfe) schon viel dazu gelernt.
Code: Alles auswählen
program pi2;
uses
mp_real, mp_types;
var
n, s: longint;
x, c: mp_float;
w: word;
begin
mpf_init2(x,c);
mpf_set0(x);
mpf_set0(c);
writeln('Pi');
write('Genauigkeit: '); readln(s);
for n:=1 to s do
begin
mpf_add_int(x,2,c);
mpf_sqrt(c,x);
end;
{x = 2^(s+1)*sqrt)2-x)}
mpf_set_int(c,2);
mpf_sub(c,x,x);
mpf_sqrt(x,x);
mpf_mul_2k(x,s+1,x);
w := 50;
writeln('Pi berechnet: ', mpf_adecimal_alt(x,w));
writeln('Pi genau: ', pi:0:50);
mpf_sub_ext(x,pi,c);
writeln('Differenz: ', mpf_adecimal_alt(c,w));
readln;
end.
Code: Alles auswählen
Pi
Genauigkeit: 30
Pi berechnet: 3.1415926535897932381825011121339387220729279189255
Pi genau: 3.14159265358979320
Differenz: -0.0000000000000000003303078472722474823598147512529
Die obige Rechnung zeigt, daß Du mit 30 Iterationen und der MPArith-Defaultgenauigkeit von ca 70 Dezimalstellen noch besser als extended Pi bist. (Mit ca 40 bist Du besser, bis ca 90 tut sich nichts, ab 100 wirds wieder schlechter)
Re: Variablentyp für lange Nachkommastellen (Pi-Berechnung)
Hallo,
Und die Differenz zu einer Konstante mit maximal 20 Stellen ist doch nicht ernst gemeint
Mit mpArith gibt es auch pi mit vielen stellen in mp_rc32.pas als Binäre Konstane mit MAX_TCBITS = 124000 ;//Bit ~37000 Dezimalen.
Gruß Horst
Meine Bemerkung zu 2^x war doch nur, weil man dann bei GMP 2**x hätte schreiben können.
Und die Differenz zu einer Konstante mit maximal 20 Stellen ist doch nicht ernst gemeint

Mit mpArith gibt es auch pi mit vielen stellen in mp_rc32.pas als Binäre Konstane mit MAX_TCBITS = 124000 ;//Bit ~37000 Dezimalen.
Code: Alles auswählen
procedure mpf_set_pip(var a: mp_float; prec: longint);
{-Set a to pi with bit precision prec}
Meine Bemerkung zu 2^x war doch nur, weil man dann bei GMP 2**x hätte schreiben können.
Re: Variablentyp für lange Nachkommastellen (Pi-Berechnung)
Achso, gut das wusste ich nicht.Horst_h hat geschrieben:Hallo,
Und die Differenz zu einer Konstante mit maximal 20 Stellen ist doch nicht ernst gemeint ;-)
Gruß Horst
Meine Bemerkung zu 2^x war doch nur, weil man dann bei GMP 2**x hätte schreiben können.
Und eigentlich dachte ich es wäre einfach einfach einen Variablentyp zu nehmen der so 100 Nachkommastellen hat und der Pi dann relativ genau bestimmen kann. Zwar wäre die Differenz in der Tat nutzlos und nur so als nettes Gimmick gedacht aber nett zum angucken :)
Was Pi als konstante angeht, ja, aber ich will es ja selbst berechnen.
@indiander-frank
Danke, ganz schon kompliziert das ganze. Wieso das nicht geeignet verstehe ich zwar nicht ganz aber wenigstens funktioniert es bis zu einer ausreichenden Nachkommastellenzahl.