2012-04-15 61 views
1

我想編程的樂趣我自己的正弦函數實現,但我不斷收到:PHP「最大執行」

Fatal error: Maximum execution time of 30 seconds exceeded 

我有一個小的HTML表單,您可以進入的「X」值Sin(x)您要查找的數量和您要計算的「迭代次數」(您的數值的精確度),其餘爲PhP。 的數學是基於正弦波的「系列定義」的維基百科: - >http://en.wikipedia.org/wiki/Sine#Series_definition 這裏是我的代碼:

<?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; 
    } 

?> 

我的錯誤可能來自一個無限循環,在這一行:

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

但我不知道如何解決這個問題。 什麼我特林在這行做的是計算:

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

迭代:

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

次以 「$ I」 的和「$ k時的 「$迭代」 量「的價值觀相應改變。

我真的被困在這裏!需要一點幫助。先謝謝你 !

順便說一句:階乘函數不是我的。我在PhP.net的評論中發現它,顯然它是最優的因子函數。

+0

您可能需要閱讀關於全球的[docs](http://php.net/global)。你不必宣佈每一個變量都是全局的,你做這件事的方式無論如何也無濟於事。 – 2012-04-15 03:43:23

回答

2

你爲什麼要計算'運算符'和'k'的功能。

sin expansion看起來像= x - x^2/2! + x^3/3! ....

這樣的事情。

還記得迭代是整數,所以對它應用intval而不是floatval。 也在網上學習如何使用全球。無論如何,你不需要全局的,因爲你的'算子'和'k'的計算將在竇性函數內。

祝你好運。

+0

謝謝,我會嘗試這個!我對PhP很新,所以我犯了很多常見的錯誤。無論如何謝謝你的幫助! – 2012-04-15 02:09:42

+0

你對如何解決無限循環問題有任何想法嗎?或者您的第一個答案中的建議是否可以解決問題?謝謝 ! – 2012-04-15 02:12:46

+1

選中此行 - $ iterations = floatval($ iterations);並嘗試逐行調試。 – 2012-04-15 02:18:10

1

對於速度,該因子函數幾乎不是最優的—儘管它並不壞。至少它不會遞歸。儘管如此,它簡單而正確。超時的主要方面是你打電話很多。提高其性能的一種技術是在本地數組中記住之前計算的階乘值。或者只計算一次。

有你的代碼中有多少位可能承受的改進:

  • 此語句:(!$迭代= 0)

如果$iterations進入爲0.1?或否定。這將導致無限循環。你可以使程序到壞輸入更耐用

while ($iterations > 0) 
  • 用於計算正弦該公式使用奇數:1,3,5,7;不是每個整數
  • 有更簡單的方法來計算交替符號。
  • 算術表達式的過度複雜化。
  • return $result在循環內,儘早終止它。

這是一個測試,工作程序,對所有這些問題的調整:這個32毫秒:

<?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"; 
} 
?> 

輸出:

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 

順便說一句,這個執行速度非常快輸出。