2012-04-15 26 views
1

私は楽しみのために私自身の正弦関数の実装をプログラムしようとしているが、私は入れません:PHP「最大実行時間」

Fatal error: Maximum execution time of 30 seconds exceeded 

私はあなたがの「X」の値を入力することができ、小さなHTMLフォームを持っていますあなたが探しているSin(x)とあなたが計算したい "反復"の数(あなたの価値の精度)、残りはPhPです。 数学は、Wikipediaのサインの「シリーズの定義」をベースとしている: - >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のそれに応じて値が変化します。

私は本当にここにこだわっています!少しの助けが必要になるでしょう。前もって感謝します !

Btw:階乗関数は私のものではありません。私はPhP.netのコメントでそれを見つけました。明らかに、それは最適な階乗関数です。

+0

[docs](http://php.net/global)をグローバルに読むことをお勧めします。あなたはすべての変数をグローバルに宣言する必要はありませんし、それをやっているやり方はとにかく助けにならないでしょう。 –

答えて

2

なぜ「演算子」と力 'k'をsinus関数の外側に計算していますか?

sin展開は= x - x^2/2のようになります! + x^3/3! ....

このようなものです。

また、反復は整数なので、floatvalではなくintvalを適用します。 また、グローバルでの使用方法をネットで調べます。とにかく、あなたの '演算子'と力の 'k'計算が副鼻腔機能の中にあるので、あなたはグローバル化する必要はありません。

幸運のベスト。

+0

ありがとう、私はこれを試してみましょう!私はPhPにはかなり新しいので、よくある間違いが多い。とにかく助けてくれてありがとう! –

+0

無限ループの問題を解決する方法はありますか?あなたの最初の答えの示唆が問題を解決するでしょうか?どうも ! –

+1

この行をチェックする - $ iterations = floatval($ iterations);行ごとにデバッグを試みてください。 –

1

その階乗関数は速度に関してはほとんど最適ではありませんが、悪くないです。少なくともそれは再発しません。しかしそれは簡単で正しいです。タイムアウトの主な側面は、それをといってもと呼んでいることです。その性能を向上させるための1つの技法は、ローカル配列において、以前に計算された階乗の値を覚えることである。あるいは、それらを一度だけ計算してください。

改善に耐えることができ、あなたのコードの多くのビットがあります。

  • この文:(!$イテレーション= 0)

    しばらくは

    $iterations場合が入力された

0.1?または否定的です。それは無限ループを引き起こします。あなたがサインを計算するための式は奇数番号を使用

while ($iterations > 0) 
  • と悪い入力にプログラムがより耐性にすることができる:1、3、5、7。すべての整数ではありません。
  • 交互符号を計算する簡単な方法があります。
  • 算術式が非常に複雑です。
  • return $resultはループ内にあり、早期に終了します。ここで

すべてのこれらの問題のための調整を持ってテストし、作業プログラムです:

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

がちなみに、これは非常に迅速に実行されます。このために32ミリ秒を出力。

関連する問題