Предупреждающее сообщение «Подразделение на ноль» является одним из наиболее часто задаваемых вопросов среди новых разработчиков PHP. Эта ошибка не вызовет исключения, поэтому некоторые разработчики будут иногда подавлять предупреждение, добавляя оператор подавления ошибок @ перед выражением. Например:
$value = @(2 / 0);
Но, как и при любом предупреждении, наилучшим подходом было бы отслеживать причину предупреждения и разрешать его. Причина предупреждения будет происходить из любого экземпляра, где вы пытаетесь разделить на 0, переменную, равную 0, или переменную, которая не была назначена (поскольку NULL == 0), потому что результат будет «неопределенным».
Чтобы исправить это предупреждение, вы должны переписать свое выражение, чтобы проверить, что значение не равно 0, если оно есть, сделать что-то еще. Если значение равно нулю, вы не должны делиться или изменять значение на 1, а затем делить так, что деление приводит к эквиваленту того, что он разделен только дополнительной переменной.
if ( $var1 == 0 ) { // check if var1 equals zero
$var1 = 1; // var1 equaled zero so change var1 to equal one instead
$var3 = ($var2 / $var1); // divide var1/var2 ie. 1/1
} else {
$var3 = ($var2 / $var1); // if var1 does not equal zero, divide
}
Вопросы, относящиеся:
C++
double LeibnizPi( double tolerance )
{
double sum = 1.0;
for( int plus_div = 5, minus_div = -3, limit = 10 / tolerance; plus_div < limit ; plus_div += 4, minus_div -= 4 )
sum += 1./plus_div + 1./minus_div;
return 4 * sum;
}
После замечания, что
(= (- (/ 4 n) (/ 4 (+ n 2))) (/ 8 n (+ n 2)))
или, в более знакомой нотации:
4 4 8 - - --- = ------ n n+2 n(n+2)
язык Common LISP, с do*
цикл (62 существенных символа):
(do* ((n 1 (+ n 4))
(p 8/3 (+ p (/ 8 n (+ n 2)))))
((< (- pi p) 1e-6)
p)
с рекурсивной функцией хвоста (70 существенных символов):
(defun l (n p)
(if (< (- pi p) 1e-6)
p
(l (+ n 4)
(+ p (/ 8 n (+ n 2))))))
(l 1 0)
и с расширенным циклом (86 существенных символов):
(loop for n from 1 by 4
sum (/ 8 n (+ n 2)) into p
until (< (- pi p) 1e-6)
finally (return p))
все под предположением, что предварительные проверки, как далеко мы должны пойти для получения желаемой точности, обманывают.
double d = 1;
double s = 1;
double pi = 0;
while(4.0 / d > 0.000001){
pi += s*4.0/d;
d+=2;
s = -s;
}
printf("%f\n", pi);
VB 117 символов :
Function Pi()
Dim t = 0D
For n = 0 To 1000000
t += Math.Pow(-1, n) / (2 * n + 1)
Next
Return 4 * t
End Function
символы VB LINQ 115 (опускающий ненужное продолжение строки) :
Function Pi()
Return 4 * Enumerable.Range(0, 1000000) _
.Sum(Function(n) Math.Pow(-1, n) / (2 * n + 1))
End Function
И затем звоните:
Sub Main()
Console.WriteLine("{0:n5}", Pi)
End Sub
Другое решение VB, с помощью довольно прохладного синтаксиса агрегирования:
Public ReadOnly Pi As Double = 4 * Aggregate i In Enumerable.Range(0, 100000) _
Select (-1) ^ i / (i * 2 + 1) Into Sum()
Выражение только: 74 символа без ненужных пробелов.
Здесь является моим в C++, вероятно, самый длинный способ сделать его: P
double pi(){
bool add = true;
double rPi = 0;
for(long i = 1; i < 99999999; i=i+2)
{
double y = (double) i;
double x = (double) 1;
if(add)
{
rPi = rPi + (x/y);
add = false;
}
else
{
rPi = rPi - (x/y);
add = true;
}
}
return (rPi * (double) 4);
}
Я просто вид записал это право после того, чтобы читать вопрос об интервью в теме на спорном мнении. Это не симпатично, но мне потребовались приблизительно 3-4 минуты, и я проверяю на точность в каждом цикле. C++. Я проснусь завтра и отправлю решение, которое не сосет:)
double get_pi(int acc)
{
double pi;
double dynamicpart;
int operationCoeff = 1;
int denom = 3;
while(1)
{
dynamicpart =
1/denom + operationCoeff*(denom+2);
pi = 4*(1-dynamicpart);
if(!(pi*acc*10-(int)pi*acc*10)) break;
)
denom+=2;
operationCoeff = -operationCoeff;
}
}
Erlang, ~126 символов:
-module (pi).
-export ([pi/0]).
pi() -> 4 * pi(0,1,1).
pi(T,M,D) ->
A = 1 / D,
if A > 0.00001
-> pi(T+(M*A), M*-1, D+2);
true -> T
end.
Эээ .... как правило, при обработке чисел следует суммировать ряды от наименьшего члена к наибольшему, чтобы избежать проблем с потерей точности. Итак, в
урезано (248 символов)
function pi(n)
pi=0.
t=10**(-n-0.5)
i=int(4/t)
i=i/2
s=-1.
do 1 j=i*2+1,1,-2
pi = pi + s/j
s=-s
1 continue
pi=abs(pi)*4
return
end
С шаблоном и комментариями (600 символов)
program leibnitz
n=5
p=int(pi(n)*10.**n)/10.**n
write(6,*)p
stop
end
c Returns pi computed to <n> digits by the leibniz formula
function pi(n)
pi=0.
c find the smallest term we need by insuring that it is too small to
c effect the interesting digits.
t=10**(-n-0.5)
i=int(4/t)
i=i/2
s=-1. ! sign of term, might be off by one, but
do 1 j=i*2+1,1,-2
pi = pi + s/j
s=-s
1 continue
pi=abs(pi)*4 ! we fix the sign problem here
return
end
вывод:
3.1415901
Кажется, он работает для произвольного количества цифр до 6 знаков, где точность из вещественных
заканчивается. Он не оптимизирован для скорости или минимального количества операций.
Java
void pi(){
double x=1,y=1,d=1;
for(;x<1E6;) { y=-y;d+=y/((2*x++)+1); }
System.out.println(d*4);
}
sum(8/(n*(n+2))for n in range(1,5**8,4))
В этой версии используется оптимизация из @ Svante answer .
print(sum(8/(n*(n+2))for n in range(1,5**8,4)))
sum(8./(n*(n+2))for n in range(1,5**8,4))
print sum(8./(n*(n+2))for n in range(1,5**8,4))
1 символ: . Написано в "MySuperDuperDomainSpecificLanguageThatOnlyReturnsThisOneAnswerAndNothingElse".
Да, это шутка, но серьезно, если вы не запретите DSL, КАЖДЫЙ конкурс Code Golf может быть выигран каким-нибудь губером, который пишет на своем языке, который использует один символ для возврата только одного результата. ..
p=4 for i=3,9^6,4 do p=p-8/i/(i+2)end print(p)