2012-04-15 9 views
1

Ich versuche, meine eigene Sinus-Funktion Implementierung für Spaß zu programmieren, aber ich bekomme immer wieder:PHP „Maximale Ausführungszeit“

Fatal error: Maximum execution time of 30 seconds exceeded 

Ich habe ein kleines HTML-Formular in dem Sie die „x“ Wert eingeben können Sin (x) suchen Sie und die Anzahl der "Iterationen", die Sie berechnen möchten (Genauigkeit Ihres Wertes), der Rest ist PhP. Die Mathematik basiert die "Baureihe Definition" von Sine auf Wikipedia: ->http://en.wikipedia.org/wiki/Sine#Series_definition Hier ist mein Code:

<?php 

    function factorial($int) { 
     if($int<2)return 1; 
     for($f=2;$int-1>1;$f*=$int--); 
     return $f; 
    }; 

    if(isset($_POST["x"]) && isset($_POST["iterations"])) { 
     $x = $_POST["x"]; 
     $iterations = $_POST["iterations"]; 
    } 
    else { 
     $error = "You forgot to enter the 'x' or the number of iterations you want."; 
     global $error; 
    } 

    if(isset($x) && is_numeric($x) && isset($iterations) && is_numeric($iterations)) { 

     $x = floatval($x); 
     $iterations = floatval($iterations); 

     for($i = 0; $i <= ($iterations-1); $i++) { 
      if($i%2 == 0) { 
       $operator = 1; 
       global $operator; 
      } 
      else { 
       $operator = -1; 
       global $operator; 
      } 
     } 

     for($k = 1; $k <= (($iterations-(1/2))*2); $k+2) { 
      $k = $k; 
      global $k; 
     } 

     function sinus($x, $iterations) { 
      if($x == 0 OR ($x%180) == 0) { 
       return 0; 
      } 
      else { 
       while($iterations != 0) { 
        $result = $result+(((pow($x, $k))/(factorial($k)))*$operator); 
        $iterations = $iterations-1; 
        return $result; 
       } 
      } 
     } 

     $result = sinus($x, $iterations); 
     global $result; 
    } 
    else if(!isset($x) OR !isset($iterations)) { 
     $error = "You forgot to enter the 'x' or the number of iterations you want."; 
     global $error; 
    } 
    else if(isset($x) && !is_numeric($x)&& isset($iterations) && is_numeric($iterations)) { 
     $error = "Not a valid number."; 
     global $error; 
    } 

?> 

Mein Fehler wahrscheinlich an dieser Linie aus einer Endlosschleife kommt:

$result = $result+(((pow($x, $k))/(factorial($k)))*$operator); 

aber ich weiß nicht, wie man das Problem löst. Was ich Tring an dieser Linie zu tun ist, zu berechnen:

((pow($x, $k))/(factorial($k)) + (((pow($x, $k))/(factorial($k)) * ($operator) 

Iterieren:

+ (((pow($x, $k))/(factorial($k)) * $operator) 

eine "$ Iterationen" Höhe der Zeit mit "$ i" 's und „$ k "Die Werte ändern sich entsprechend.

Ich bin wirklich hier stecken! Ein bisschen Hilfe wäre nötig. Vielen Dank im Voraus !

Btw: Die Fakultät Funktion ist nicht meins. Ich habe es in einem Kommentar von PhP.net gefunden und anscheinend ist es die optimale faktorielle Funktion.

+0

Vielleicht möchten Sie die [Docs] (http://php.net/global) auf global lesen. Sie müssen nicht jede Variable global deklarieren, und die Art, wie Sie es tun, würde sowieso nicht helfen. –

Antwort

2

Warum berechnen Sie den "Operator" und "k" außerhalb der Sinus-Funktion.

sin Erweiterung sieht aus wie = x - x^2/2! + x^3/3! ....

so etwas wie das.

Auch erinnern Iteration ist Ganzzahl, so gelten Intval auf und nicht Floatval. Auch im Netz lernen, wie man global verwendet. Auf jeden Fall brauchen Sie nicht global, weil Ihre 'Operator' und Power 'k' Berechnung innerhalb der Sinus-Funktion sein wird.

Viel Glück.

+0

Danke, ich werde das versuchen! Ich bin ziemlich neu bei PhP, deshalb mache ich viele häufige Fehler. Wie auch immer, danke für deine Hilfe! –

+0

Haben Sie eine Idee, wie Sie das Endlosschleife Problem lösen können? Oder lösen die Vorschläge in Ihrer ersten Antwort das Problem? Danke ! –

+1

Überprüfen Sie diese Zeile - $ iterations = floatval ($ iterations); und versuchen Sie, Zeile für Zeile zu debuggen. –

1

Diese faktorielle Funktion ist kaum optimal — für Geschwindigkeit, obwohl es nicht schlecht ist. Wenigstens rekurriert es nicht. Es ist jedoch einfach und korrekt. Der Hauptaspekt des Timeouts ist, dass Sie es viel nennen. Eine Technik zum Verbessern ihrer Leistung besteht darin, sich in einem lokalen Array die Werte für das früher berechnete Faktorium zu merken. Oder berechne sie alle nur einmal.

Es gibt viele Bits des Codes, die Verbesserung ertragen konnte:

  • Diese Aussage: (! $ Iterationen = 0)

    während

Was passiert, wenn $iterations eingegeben als 0,1? Oder negativ. Das würde eine Endlosschleife verursachen.Sie können das Programm beständige gegen schlechten Eingang bilden mit

while ($iterations > 0) 
  • die Formel eine sinus zum Berechnen der ungeraden Zahlen verwendet: 1, 3, 5, 7; nicht jede ganze Zahl
  • Es gibt einfachere Möglichkeiten, das alternierende Zeichen zu berechnen.
  • Übermäßige Komplikation der arithmetischen Ausdrücke.
  • return $result ist innerhalb der Schleife und beendet es früh.

Hier ist eine erprobte, Arbeitsprogramm, die Anpassungen für all diese Fragen hat:

<?php 
// precompute the factorial values 
global $factorials; 
$factorials = array(); 
foreach (range (0, 170) as $j) 
     if ($j < 2) 
       $factorials [$j] = 1; 
     else $factorials [$j] = $factorials [$j-1] * $j; 

function sinus($x, $iterations) 
{ 
     global $factorials; 

     $sign = 1; 
     for ($j = 1, $result = 0; $j < $iterations * 2; $j += 2) 
     { 
       $result += pow($x, $j)/$factorials[$j] * $sign; 
       $sign = - $sign; 
     } 
     return $result; 
} 

// test program to prove functionality 
$pi = 3.14159265358979323846264338327950288419716939937510582097494459230781640628620; 
$x_vals = array (0, $pi/4, $pi/2, $pi, $pi * 3/2, 2 * $pi); 

foreach ($x_vals as $x) 
{ 
     $y = sinus ($x, 20); 
     echo "sinus($x) = $y\n"; 
} 
?> 

Ausgang:

sinus(0) = 0 
sinus(0.78539816339745) = 0.70710678118655 
sinus(1.5707963267949) = 1 
sinus(3.1415926535898) = 3.4586691443274E-16 
sinus(4.7123889803847) = -1 
sinus(6.2831853071796) = 8.9457384260403E-15 

By the way, diese sehr schnell ausführt: 32 Millisekunden für diese Ausgabe.

Verwandte Themen