2012-04-15 5 views
1

나는 재미를 위해 내 자신의 사인 기능 구현을 프로그래밍하기 위해 노력하고있어하지만 난 점점 계속 : PHP "최대 실행 시간"

Fatal error: Maximum execution time of 30 seconds exceeded 

나는 당신의 "X"값을 입력 할 수있는 작은 HTML 양식을 가지고 죄 (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를 가진 시간의"$ 반복 "양 "그에 따라 값이 변합니다.

나는 정말 여기에 붙어 있습니다! 약간의 도움이 필요할 것입니다. 미리 감사드립니다.

Btw : 계승 함수가 내 것이 아닙니다. 나는 PhP.net 주석에서 그것을 발견했으며 그것은 분명히 최적의 계승 함수이다.

+0

[docs] (http://php.net/global) 전역을 읽을 수 있습니다. 당신은 모든 변수를 전역 변수로 선언 할 필요가 없습니다. 그리고 당신이하고있는 방식이 어쨌든 도움이되지 않을 것입니다. –

답변

2

왜 '연산자'와 힘 'k'를 부비동 기능 밖으로 계산하고 있습니까?

sin 확장은 다음과 같습니다. = x - x^2/2! + x^3/3! ....

이런 식으로.

또한 iteration은 정수이므로 floatval이 아닌 intval을 적용하십시오. 그물을 사용하는 방법에 대해 자세히 알아보십시오. 어쨌든 당신은 '연산자'와 힘 'k'계산이 부비동 기능 내에 있기 때문에 전역이 필요하지 않습니다.

행운을 빈다.

+0

감사합니다! 나는 PhP를 처음 사용하기 때문에 일반적인 실수를 많이합니다. 어쨌든 도와 주셔서 감사합니다! –

+0

무한 루프 문제를 해결하는 방법에 대한 아이디어가 있습니까? 또는 첫 번째 대답의 제안이 문제를 해결할 것입니까? 고마워 ! –

+1

이 줄을 확인하십시오 - $ iterations = floatval ($ iterations); 라인별로 디버그를 시도하십시오. –

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 
      

      , 이것은 매우 빠르게 실행 여기에

  • 이러한 모든 문제에 대한 조정이있는 테스트 작업 프로그램입니다 산출.