Bestimmt hat schon einmal so mancher Programmierer mit der Idee gespielt, ein Programm zu schreiben, welches die transzendenten Zahlen e und pi auf mindestens mehrere dutzend Dezimalstellen genau zu berechnen. Doch leider ist dies nicht so leicht möglich, weil die Fließkommazahlenbereiche der üblichen Programmiersprachen eine beschränkte, festgelegte Genauigkeit haben.
Ein möglicher Ausweg aus diesem Dilemma besteht zum Beispiel darin, Zahlen als Zeichenketten zu behandeln und den Computer beizubringen mit diesen auf die gleiche Weise zu rechnen, wie man es in der Schule gelernt hat, als es noch keine Taschenrechner und Computer gab.
Die Beschränkung ist in diesem Fall durch die maximale Länge von Zeichenketten gegeben, welche sich von Programmiersprache zu Programmiersprache unterscheidet, aber bei modernen Programmiersprachen in der Regel höher ist als die größten standardmäßig verarbeitbaren Fließkommazahlen .
Allerdings hat diese Methode zu rechnen eine sehr schlechte Performance, die zu langen Programmlaufzeiten führt, was aber bei der Bestimmung von irrationalen Zahlen mit hoher Genauigkeit nur von geringer Bedeutung ist. Im Folgenden ist ein php-Programm publiziert, welches nach dieser Methode die Zahlen e und pi mit höchster Genauigkeit berechnen kann, wobei als Grundlage für die Berechnung von pi die Formel 16 * arctan(1/5)-4*arctan(1/239) dient und für die Berechnung von e die Summe der Kehrwerte der Fakultäten.
Hier der Code
<?php
$Wunschzahl = "e";
if ($Wunschzahl === "pi")
{
//$e = E_Wert();
$Schrittzahl = 100;
$Schrittzahl1 = ceil(4 + $Schrittzahl* (log(5))/(log(239)));
$Schrittzahl2 = ceil(0.75 * $Schrittzahl);
$pi = Pi_Wert ( $Schrittzahl, $Schrittzahl1, $Schrittzahl2);
//echo $e."\n ";
echo "Berechnung von pi\n\n pi = ".$pi."\n auf ".(string)($Schrittzahl2 - 2). " Nachkommastellen genau berechnet.\n\n\n\nSchrittzahlen\n\nArkustangens 1/5 mit ".$Schrittzahl." Schritten berechnet.\nArkustangens 1/239 mit ".$Schrittzahl1." Schritten berechnet.\nDivision mit ".$Schrittzahl2." Schritten berechnet.";
echo"\n\n";
}
if ($Wunschzahl === "e")
{
$Schrittzahl = 250;
$Schrittzahl1 = ceil(0.75 * $Schrittzahl);
$Schrittzahl1 = 202;
$e = E_Wert( $Schrittzahl, $Schrittzahl1);
echo "Berechnung von e\n\n e = ".$e."\n auf ".(string)($Schrittzahl1 - 2). " Nachkommastellen genau berechnet.\n\n\n\nSchrittzahlen\n\nKehrwerte Fakultätsreihe mit ".$Schrittzahl." Schritten berechnet.\nDivision mit ".$Schrittzahl1." Schritten berechnet.";
echo"\n\n";
}
?>
<?php
function Stradd ($a, $b )
//Addition von 2 Zahlen als String, ermöglicht Addition beliebig grosser Zahlen
{
$a = str_replace(",",".",$a);
$b = str_replace(",",".",$b);
if (strpos($a,".") == false)
{
$a1 =$a;
$a2 = "0";
}
else
{
$a1 = substr($a,0,strpos($a,"."));
$a2 = substr($a,1 + strpos($a,"."));
}
if (strpos($b,".") == false)
{
$b1 =$b;
$b2 = "0";
}
else
{
$b1 = substr($b,0,strpos($b,"."));
$b2 = substr($b,1 + strpos($b,"."));
}
while (strlen($a1) < strlen($b1))
{
$a1 = "0".$a1;
}
while (strlen($b1) < strlen($a1))
{
$b1 = "0".$b1;
}
$a1 ="0".$a1;
$b1 ="0".$b1;
while (strlen($a2) < strlen($b2))
{
$a2 = $a2."0";
}
while (strlen($b2) < strlen($a2))
{
$b2 = $b2."0";
}
$a = $a1.".".$a2;
$b = $b1.".".$b2;
//echo $a. "$".$b."X\n";
$i = 0;
$u = 0;
$d ="";
while ($i < strlen($a))
{
$i = $i + 1;
$c1 = substr($a,strlen($a) - $i,1);
$c2 = substr($b,strlen($b) - $i,1);
if ($c1 == ".")
{
$d = $d.".";
}
else
{
$d = $d.( string )(($c1 + $c2 + $u) %10);
$u = ( int )(($c1 + $c2 + $u) / 10.0);
}
//echo $c1;
}
$d = strrev($d);
while (substr($d,0,1) == "0")
{
$d = substr($d,1);
}
//echo "\n".$d."\n";
return $d;
}
?>
<?php
function Strsub ($a, $b )
//Subtraktion von 2 Zahlen als String, ermöglicht Subtraktion beliebig grosser Zahlen
{
$a = str_replace(",",".",$a);
$b = str_replace(",",".",$b);
if (strpos($a,".") == false)
{
$a1 =$a;
$a2 = "0";
}
else
{
$a1 = substr($a,0,strpos($a,"."));
$a2 = substr($a,1 + strpos($a,"."));
}
if (strpos($b,".") == false)
{
$b1 =$b;
$b2 = "0";
}
else
{
$b1 = substr($b,0,strpos($b,"."));
$b2 = substr($b,1 + strpos($b,"."));
}
while (strlen($a1) < strlen($b1))
{
$a1 = "0".$a1;
}
while (strlen($b1) < strlen($a1))
{
$b1 = "0".$b1;
}
$a1 ="0".$a1;
$b1 ="0".$b1;
while (strlen($a2) < strlen($b2))
{
$a2 = $a2."0";
}
while (strlen($b2) < strlen($a2))
{
$b2 = $b2."0";
}
$a = $a1.".".$a2;
$b = $b1.".".$b2;
$i = 0;
$u = 0;
$d ="";
while ($i < strlen($a))
{
$c1 = (int)substr($a,$i,1);
$c2 = (int)substr($b,$i,1);
if ($c2 == $c1)
{
$i = $i + 1;
}
else
{
$i = strlen($a);
if ($c2 > $c1)
{
$i = strlen($a);
$tauschen = true;
}
else
{
$i = strlen($a);
$tauschen = false;
}
}
}
if ($tauschen === true)
{
$H = $b;
$b = $a;
$a = $H;
}
//echo $a. "$".$b."X\n";
$i = 0;
$u = 0;
$d ="";
while ($i < strlen($a))
{
$i = $i + 1;
$c1 = substr($a,strlen($a) - $i,1);
$c2 = substr($b,strlen($b) - $i,1);
if ($c1 == ".")
{
$d = $d.".";
}
else
{
if (($c1 - $c2 - $u) < 0)
{
$d = $d.( string )($c1 - $c2 - $u + 10);
$u = 1;
}
else
{
$d = $d.( string )($c1 - $c2 - $u);
$u = 0;
}
}
//echo $c1;
}
$d = strrev($d);
while (substr($d,0,1) == "0")
{
$d = substr($d,1);
}
if($tauschen === true)
{
$d = "-".$d;
}
//echo "\n".$d."\n";
return $d;
}
?>
<?php
function Strmult ($a, $b )
//Multiplikation von 2 Zahlen als String, ermöglicht Multiplikation beliebig grosser Zahlen
{
$a = str_replace(",",".",$a);
$b = str_replace(",",".",$b);
if (stripos($a,".") === FALSE)
{
$Dezimalzahl_a = 0;
}
else
{
$Dezimalzahl_a = strlen($a) - stripos($a,".") - 1;
}
if (stripos($b,".") === FALSE)
{
$Dezimalzahl_b = 0;
}
else
{
$Dezimalzahl_b = strlen($b) - stripos($b,".") - 1;
}
$Dezimalzahl_Ergebnis = $Dezimalzahl_a + $Dezimalzahl_b;
//echo "Dezimalen von a:".$Dezimalzahl_a."\n";
$a = str_replace(".","",$a);
$b = str_replace(".","",$b);
$Laenge = strlen($b);
//echo $a. "$".$b."X\n";
$k = 0;
while ($k < strlen($b))
{
$i = 0;
$u = 0;
$d[$k] ="";
$c2 = substr($b,strlen($b) - $k - 1,1);
while ($i < strlen($a))
{
$i = $i + 1;
$c1 = substr($a,strlen($a) - $i,1);
if ($i == strlen($a))
{
$d[$k] = $d[$k].(strrev(( string )($c1 * $c2 + $u)));
//echo "\nh".$d[$k].( string )($c1 * $c2 + $u)."\n";
}
else
{
if ($c1 == ".")
{
$d[$k] = $d[$k].".";
}
else
{
$d[$k] = $d[$k].( string )(($c1 * $c2 + $u) %10);
//echo "\nt".$d[$k]."\n";
$u = ( int )(($c1 * $c2 + $u) / 10.0);
}
}
//echo $c1;
}
$d[$k] = strrev($d[$k]);
$k = $k + 1;
}
$k = strlen($b) - 1;
while ($k > -1)
{
$k2 = $k;
$M = $d[$k];
while ($k2 > 0)
{
$M = $M."0";
$k2 = $k2 - 1;
}
$d[$k] = $M;
//echo "\n".$d[$k]."k=".$k."\n";
$k = $k - 1;
}
$k = 0;
while ($k < $Laenge)
{
while (strlen($d[$k])< strlen($d[$Laenge - 1]))
{
$d[$k] = "0".($d[$k]);
}
//echo "M=".$d[$k]."K=".$k." Länge=".$Laenge;
$k = $k +1;
}
$i = 0;
//echo "R".$b;
$i = 0;
$uebertrag = 0;
$Ergebnis = "";
while ($i < strlen($d[0]))
{
$k = 0;
$c2 = 0;
while ($k < strlen($b))
{
$c2 = $c2 + (int)(substr($d[$k],strlen($d[$k]) - $i - 1,1));
//echo "\n k=".$k.": ".$c2."\n";
$k = $k +1;
}
$c2 = $c2 + $uebertrag;
$uebertrag = ( int )($c2 / 10.0);
if ($i == -1 + strlen($d[0]))
{
$Ergebnis = $Ergebnis.strrev( ( string )($c2));
//echo "c2=".$c2." k=".$i. " Ergebnis =".$Ergebnis." Übertrag =".$uebertrag;
}
else
{
$Ergebnis = $Ergebnis.( string )($c2 %10);
//echo "C2=".$c2." k=".$i. " Ergebnis =".$Ergebnis." Übertrag =".$uebertrag;
}
$i = $i + 1;
}
$Ergebnis = strrev($Ergebnis);
$Kommastelle = strlen($Ergebnis) - $Dezimalzahl_a - $Dezimalzahl_b;
$Ergebnis = substr($Ergebnis,0,$Kommastelle).",".substr($Ergebnis,$Kommastelle);
return $Ergebnis;
//echo "c2final=".$c2." k=".$i. " Ergebnis =".$Ergebnis;
}
?>
<?php
function Strdiv ($a, $b, $Schrittzahl )
//Subtraktion von 2 Zahlen als String, ermöglicht Subtraktion beliebig grosser Zahlen
{
//$Schrittzahl = 60; //Legt die Zahl der Schritte fest. Darf verändert werden!
$a = str_replace(",",".",$a);
$b = str_replace(",",".",$b);
if (stripos($a,".") === FALSE)
{
$Dezimalzahl_a = 0;
}
else
{
$Dezimalzahl_a = strlen($a) - stripos($a,".") - 1;
}
if (stripos($b,".") === FALSE)
{
$Dezimalzahl_b = 0;
}
else
{
$Dezimalzahl_b = strlen($b) - stripos($b,".") - 1;
}
while ($Dezimalzahl_a < $Dezimalzahl_b)
{
$a = $a."0";
$Dezimalzahl_a = $Dezimalzahl_a + 1;
}
while ($Dezimalzahl_b < $Dezimalzahl_a)
{
$b = $b."0";
$Dezimalzahl_b = $Dezimalzahl_b + 1;
}
$a = str_replace(".","",$a);
$b = str_replace(".","",$b);
$a = ltrim($a,"0");
$b = ltrim($b,"0");
//echo "a =".$a." b=".$b."\n\n";
$Ergebnis ="";
$i = 0;
$Komma ="";
while (strlen($a) < strlen($b))
{
$a = $a."0";
if ($i === 0)
{
$Ergebnis =$Ergebnis."0,";
$Komma = "J";
}
else
{
$Ergebnis =$Ergebnis."0";
}
$i = $i + 1;
}
$a2 = substr($a,0,strlen($b));
$k = 0; //Zähler für noch zu realisierende äussere Schleife
while ($k < $Schrittzahl)
{
//echo "b =".$b." a2=".$a2;
$j = 0;
$stop = 0;
while ($stop == 0)
{
//Grössenvergleich
$i = 0;
while (strlen($b) < strlen($a2))
{
$b = "0".$b;
}
while ($i < strlen($a2))
{
$c1 = (int)substr($a2,$i,1);
$c2 = (int)substr($b,$i,1);
if ($c2 == $c1)
{
$i = $i + 1;
}
else
{
$i = strlen($a2);
if ($c2 > $c1)
{
$i = strlen($a2);
$stop = 1;
}
else
{
$i = strlen($a2);
$stop = 0;
}
}
}
//echo "Stop =".$stop;
// Subtraktion
if ($stop == 0)
{
$i = 0;
$u = 0;
$d ="";
while ($i < strlen($a2))
{
$i = $i + 1;
$c1 = substr($a2,strlen($a2) - $i,1);
$c2 = substr($b,strlen($b) - $i,1);
if ($c1 == ".")
{
$d = $d.".";
}
else
{
if (($c1 - $c2 - $u) < 0)
{
$d = $d.( string )($c1 - $c2 - $u + 10);
$u = 1;
}
else
{
$d = $d.( string )($c1 - $c2 - $u);
$u = 0;
}
}
//echo $c1;
}
$d = strrev($d);
//echo "d = ".$d;
$j = $j + 1;
}
else
{
$d = $a2;
}
$a2 = $d;
//echo "j =".$j." a2(else von if (stop == 0)=".$a2;
//$stop = 1;
}
$a2 = ltrim($a2,"0");
$b = ltrim($b,"0");
//echo "Getrimmtes a2 =".$a2;
if ($a2 == "")
{
$a2 = "0";
}
//echo "j =".$j." a2=".$a2;
if ((strlen($a)) > ($k + strlen($b)))
{
$a2 = $a2.substr($a, $k + strlen($b),1);
}
else
{
$a2 = $a2."0";
}
//echo " a2( nach Übertrag)) =".$a2;
//echo " j =".$j." a2=".$a;
if (((strlen($a)) === (-1 + $k + strlen($b))) and ($Komma ===""))
{
$Ergebnis = $Ergebnis.",".$j;
}
else
{
$Ergebnis = $Ergebnis.$j;
}
$k = $k + 1;
}//Ende while ( k<)
$Ergebnis = ltrim($Ergebnis,"0");
if (substr($Ergebnis,0,1) ===",")
{
$Ergebnis = "0".$Ergebnis;
}
//echo "Ergebnis = ".$Ergebnis;
return $Ergebnis;
}
?>
<?php
function Arcustangens ($a, $b)
{
$k = 0;
$a3 = "0";
$b3 = "1";
$Schrittzahl = 10; //Legt die Zahl der Schritte fest. Darf verändert werden
while ( $k < $Schrittzahl)
{
$j = 0;
$a2 = "1";
$b2 = "1";
while ($j < (2*$k +1))
{
//$a2 = $a2 * $a;
$a2 = Strmult($a2,$a);
//$b2 = $b2*$b;
$b2 = Strmult($b2,$b);
$j = $j + 1;
}
//$b2 = $b2*(2*$k +1);
$b2 = Strmult($b2, (string)(2*$k +1));
if (($k % 2) === 1)
{
$a3 =Strsub(Strmult($a3,$b2),Strmult($a2,$b3));
//$a3 = $a3*$b2 - $a2*$b3;
//$b3 = $b2 * $b3;
$b3 = Strmult($b2,$b3);
}
else
{
$a3 =Stradd(Strmult($a3,$b2),Strmult($a2,$b3));
//$a3 = $a3*$b2 + $a2*$b3;
//$b3 = $b2 * $b3;
$b3 = Strmult($b2,$b3);
}
$k = $k + 1;
}
echo $a3."/".$b3;
Strdiv ($a3, $b3 );
}
?>
<?php
function Pi_Wert ($Schrittzahl, $Schrittzahl1, $Schrittzahl2)
{
$a = "1";
$b= "5";
$k = 0;
$a3 = "0";
$b3 = "1";
$Schrittzahl = 100; //Legt die Zahl der Schritte fest. Darf verändert werden!
while ( $k < $Schrittzahl)
{
$j = 0;
$a2 = "1";
$b2 = "1";
while ($j < (2*$k +1))
{
//$a2 = $a2 * $a;
$a2 = Strmult($a2,$a);
//$b2 = $b2*$b;
$b2 = Strmult($b2,$b);
$j = $j + 1;
}
//$b2 = $b2*(2*$k +1);
$b2 = Strmult($b2, (string)(2*$k +1));
if (($k % 2) === 1)
{
$a3 =Strsub(Strmult($a3,$b2),Strmult($a2,$b3));
//$a3 = $a3*$b2 - $a2*$b3;
//$b3 = $b2 * $b3;
$b3 = Strmult($b2,$b3);
}
else
{
$a3 =Stradd(Strmult($a3,$b2),Strmult($a2,$b3));
//$a3 = $a3*$b2 + $a2*$b3;
//$b3 = $b2 * $b3;
$b3 = Strmult($b2,$b3);
}
$k = $k + 1;
}
//echo $a3."/".$b3;
//Strdiv ($a3, $b3 );
$a4 = Strmult("16",$a3);
$b4 = $b3;
$a = "1";
$b= "239";
$k = 0;
$a3 = "0";
$b3 = "1";
while ( $k < $Schrittzahl1)
{
$j = 0;
$a2 = "1";
$b2 = "1";
while ($j < (2*$k +1))
{
//$a2 = $a2 * $a;
$a2 = Strmult($a2,$a);
//$b2 = $b2*$b;
$b2 = Strmult($b2,$b);
$j = $j + 1;
}
//$b2 = $b2*(2*$k +1);
$b2 = Strmult($b2, (string)(2*$k +1));
if (($k % 2) === 1)
{
$a3 =Strsub(Strmult($a3,$b2),Strmult($a2,$b3));
//$a3 = $a3*$b2 - $a2*$b3;
//$b3 = $b2 * $b3;
$b3 = Strmult($b2,$b3);
}
else
{
$a3 =Stradd(Strmult($a3,$b2),Strmult($a2,$b3));
//$a3 = $a3*$b2 + $a2*$b3;
//$b3 = $b2 * $b3;
$b3 = Strmult($b2,$b3);
}
$k = $k + 1;
}
//echo $a3."/".$b3;
//Strdiv ($a3, $b3 );
$a3 = Strmult("4",$a3);
$a4 =Strsub(Strmult($a4,$b3),Strmult($a3,$b4));
$b4 =Strmult($b3,$b4);
return(Strdiv ($a4, $b4, $Schrittzahl2 ));
//echo $a3."/".$b3;
//Strdiv ($a3, $b3 );
}
?>
<?php
function E_Wert( $Grenzwert, $Schrittzahl1)
{
$a = "1";
$k = 0;
$b = "1";
$c = "1";
$d = "1";
while ($k < ($Grenzwert + 1))
{
$j = 1;
$f = "1";
while ($j < ($k + 2))
{
//$f = $f*$j;
$f = Strmult($f, (string)$j);
$j = $j + 1;
}
//$b =$b*$f + $c*$d;
$b = Stradd((Strmult($b,$f)),Strmult($c,$d));
//$c = $c*$f;
$c = Strmult($c,$f);
$k = $k + 1;
}
return (Strdiv($b,$c, $Schrittzahl1));
}
?>
Programmbeispiel
Berechnung von pi
pi = 3,14159265358979323846264338327950288419716939937510582097494459230781
auf 68 Nachkommastellen genau berechnet.
Schrittzahlen
Arkustangens 1/5 mit 100 Schritten berechnet.
Arkustangens 1/239 mit 34 Schritten berechnet.
Division mit 70 Schritten berechnet.
Programmlaufzeit: 3h31m52s
(Dieser Beitrag wurde von Aldemarin am 29. Aug 2013, 09:50 geändert)