2012-04-15 2 views
1

Я пытаюсь программировать свою собственную Sine реализации функции для удовольствия, но я получаю:PHP «Максимальное время выполнения»

Fatal error: Maximum execution time of 30 seconds exceeded 

У меня есть небольшой HTML-форма, где вы можете ввести «х» значение 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» 'с и «$ к "соответственно меняются значения.

Я действительно застрял здесь! Нужна помощь. Заранее спасибо !

Btw: Факториальная функция не моя. Я нашел его в комментарии PhP.net и, по-видимому, это оптимальная факториальная функция.

+0

Возможно, вы захотите прочитать [docs] (http://php.net/global) на глобальном уровне. Вам не нужно объявлять каждую переменную global, и то, как вы это делаете, никоим образом не поможет. –

ответ

2

Почему вы вычисляете «оператор» и мощность «k» вне функции синуса.

Расширение греха выглядит как = x - x^2/2! + x^3/3! ....

что-то вроде этого.

Также помните, что итерация целая, поэтому на ней накладываем intval, а не floatval. Также изучите в сети, как использовать глобальные. В любом случае вам не нужен глобальный, потому что ваше вычисление «оператор» и мощность «k» будет находиться в синусовой функции.

Удачи.

+0

Спасибо, я попробую! Я довольно новичок в PhP, поэтому у меня много распространенных ошибок. В любом случае спасибо за вашу помощь! –

+0

Есть ли у вас какие-либо идеи о том, как решить проблему бесконечного цикла? или будут ли предложения в вашем первом ответе решить проблему? спасибо ! –

+1

Проверьте эту строку - $ iterations = floatval ($ iterations); и попробуйте отладить строку за строкой. –

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 миллисекунд для этого вывод.

Смежные вопросы