Предупреждающее сообщение «Подразделение на ноль» является одним из наиболее часто задаваемых вопросов среди новых разработчиков 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
}
Вопросы, относящиеся:
Дж, 14 символов
4*-/%>:+:i.1e6
<час> Объяснение
1e6
является номером 1, сопровождаемым 6, обнуляет (1000000). i.y
генерирует первое y
не отрицательные числа. +:
функция, которая удваивает каждый элемент в аргументе списка. >:
функция, которая увеличивает одним каждым элементом в аргументе списка. Так, выражение >:+:i.1e6
генерирует первый один миллион нечетных чисел:
1 3 5 7...
%
взаимный оператор (числитель "1" может быть опущен). -/
делает альтернативную сумму каждого элемента в аргументе списка. Так, выражение -/%>:+:i.1e6
генерирует альтернативную сумму обратных величин первого одного миллиона нечетных чисел:
1 - 1/3 + 1/5 - 1/7 +...
4*
умножение четыре. Если Вы умножаетесь на четыре предыдущая сумма, у Вас есть ПЂ. Вот именно! J является мощным языком для математики.
<час>Редактирование : начиная с генерации 9! (362880) условия за альтернативную сумму достаточны для имения 5 точности десятичной цифры, и так как формула Leibniz может быть записана также этот путь:
4 - 4/3 + 4/5 - 4/7 +...
... можно записать более короткое, 12 символов версия программы:
-/4%>:+:i.9!
Ruby:
irb(main):031:0> 4*(1..10000).inject {|s,x| s+(-1)**(x+1)*1.0/(2*x-1)}
=> 3.14149265359003
64 символа в AWK:
~# awk 'BEGIN {p=1;for(i=3;i<10^6;i+=4){p=p-1/i+1/(i+2)}print p*4}'
3.14159
обман C# - 50 символов :
static single Pi(){
return Math.Round(Math.PI, 5));
}
Это только говорит "принятие во внимание, что формула пишет функцию...", это не говорит, воспроизводят формулу программно:) Думают вне поля...
C# LINQ - 78 символов :
static double pi = 4 * Enumerable.Range(0, 1000000)
.Sum(n => Math.Pow(-1, n) / (2 * n + 1));
Альтернатива C# LINQ - 94 символа :
static double pi = return 4 * (from n in Enumerable.Range(0, 1000000)
select Math.Pow(-1, n) / (2 * n + 1)).Sum();
И наконец - это берет ранее упомянутый алгоритм и уплотняет его математически, таким образом, Вы не должны волноваться о знаках изменяющего содержания.
обычное письмо C# - 89 символов (не считающий необязательные пробелы) :
static double pi()
{
var t = 0D;
for (int n = 0; n < 1e6; t += Math.Pow(-1, n) / (2 * n + 1), n++) ;
return 4 * t;
}
#!/usr/bin/env python
from math import *
denom = 1.0
imm = 0.0
sgn = 1
it = 0
for i in xrange(0, int(1e6)):
imm += (sgn*1/denom)
denom += 2
sgn *= -1
print str(4*imm)
dc -e '9k0 1[d4r/r2+sar-lad274899>b]dsbxrp'
Язык: C99 (неявный возврат 0), Символьное количество: 99 (95 + 4 требуемых пространства)
условие выхода зависит от текущего значения, не от уплотненной версии
#include<stdio.h>
float
p,s=4,d=1;int
main(void){for(;4/d>1E-5;d+=2)p-=(s=-s)/d;printf("%g\n",p);}
фиксированного количества #include <stdio.h>
float p, s=4, d=1;
int main(void) {
for (; 4/d > 1E-5; d += 2)
p -= (s = -s) / d;
printf("%g\n", p);
}
Большинство текущих ответов предполагает, что они получат 5 точности цифр в некотором количестве повторений, и это число является hardcoded в программу. Мое понимание вопроса было то, что сама программа, как предполагается, выясняет, когда это имеет ответ с точностью до 5 цифр и остановки там. На том предположении вот мое решение C#. Я не потрудился минимизировать количество символов, так как нет никакого способа, которым оно уже может конкурировать с некоторыми ответами там, таким образом, я думал, что сделаю его читаемым вместо этого.:)
private static double GetPi()
{
double acc = 1, sign = -1, lastCheck = 0;
for (double div = 3; ; div += 2, sign *= -1)
{
acc += sign / div;
double currPi = acc * 4;
double currCheck = Math.Round(currPi, 5);
if (currCheck == lastCheck)
return currPi;
lastCheck = currCheck;
}
}
Вот рекурсивный ответ с помощью C#. Это будет только работать с помощью x64 JIT в режиме Release, потому что это - единственный JIT, который применяет оптимизацию последнего вызова, и поскольку ряд сходится так медленно, это приведет к StackOverflowException
без него.
было бы хорошо иметь эти IteratePi
функция как анонимная лямбда, но поскольку это саморекурсивно, мы должны были бы начать делать весь способ ужасных вещей с Y-combinators, таким образом, я оставил его как отдельную функцию.
public static double CalculatePi()
{
return IteratePi(0.0, 1.0, true);
}
private static double IteratePi(double result, double denom, bool add)
{
var term = 4.0 / denom;
if (term < 0.00001) return result;
var next = add ? result + term : result - term;
return IteratePi(next, denom + 2.0, !add);
}
Язык: Brainfuck, Символьное количество: 51/59
Проводит этот подсчет? =]
, поскольку нет никаких чисел с плавающей запятой в Brainfuck, было довольно трудно получить подразделения, работающие правильно. Grr.
Без новой строки (51):
+++++++[>+++++++<-]>++.-----.+++.+++.---.++++.++++.
С новой строкой (59):
+++++++[>+++++++>+<<-]>++.-----.+++.+++.---.++++.++++.>+++.
26 просто функция, 27 для вычисления, 31 для печати. От комментариев до этот ответ .
sub _{$-++<1e6&&4/$-++-&_} # just the sub
sub _{$-++<1e6&&4/$-++-&_}_ # compute
sub _{$-++<1e6&&4/$-++-&_}say _ # print
28 просто вычислений, 34 для печати. Из комментариев. Обратите внимание, что эта версия не может использовать, 'говорят'.
$.=.5;$\=2/$.++-$\for 1..1e6 # no print
$.=.5;$\=2/$.++-$\for$...1e6;print # do print, with bonus obfuscation
36 просто вычислений, 42 для печати. Взятие Гудзона при перестановке dreeves, из комментариев.
$/++;$\+=8/$//($/+2),$/+=4for$/..1e6
$/++;$\+=8/$//($/+2),$/+=4for$/..1e6;print
Об итеративном количестве: насколько мои математические памяти идут, 400000 доказуемо достаточно, чтобы быть с точностью до 0,00001. Но миллион (или настолько же низко как 8e5) на самом деле заставляет десятичное расширение на самом деле соответствовать 5 дробным местам, и это - тот же счетчик символов, таким образом, я сохранил это.
Ruby, 33 символа
(0..1e6).inject{|a,b|2/(0.5-b)-a}
Другая версия C#:
(60 символов)
4*Enumerable.Range(0, 500000).Sum(x => Math.Pow(-1, x)/(2*x + 1)); // = 3,14159
52 символа в Python :
print 4*sum(((-1.)**i/(2*i+1)for i in xrange(5**8)))
(51 отбрасывание 'x' от xrange.)
36 символов в Октаве (или Matlab):
l=0:5^8;disp((-1).^l*(4./(2.*l+1))')
(выполняют "формат долго"; показать все значащие цифры.) Опускающий 'disp' мы достигаем 30 символов:
octave:5> l=0:5^8;(-1).^l*(4./(2.*l+1))'
ans = 3.14159009359631
символы Oracle SQL 73
select -4*sum(power(-1,level)/(level*2-1)) from dual connect by level<1e6
Язык: C, Символьное количество: 71
float p;main(i){for(i=1;1E6/i>5;i+=2)p-=(i%4-2)*4./i;printf("%g\n",p);}
Язык: C99, Символьное количество: 97 (включая необходимую новую строку)
#include <stdio.h>
float p;int main(){for(int i=1;1E6/i>5;i+=2)p-=(i%4-2)*4./i;printf("%g\n",p);}
я должен отметить, что вышеупомянутые версии (которые являются тем же) отслеживают то, влияло ли дополнительное повторение на результат вообще. Таким образом это выполняет минимальное количество операций. Для добавления большего количества цифр замените 1E6
1E(num_digits+1)
или 4E5
с 4E(num_digits)
(в зависимости от версии). Для полных программ, %g
, возможно, должен быть заменен. float
, возможно, должен быть изменен на [1 110] также.
Язык: C, Символьное количество: 67 (см. примечания)
double p,i=1;main(){for(;i<1E6;i+=4)p+=8/i/(i+2);printf("%g\n",p);}
Эта версия использует измененную версию отправленного алгоритма, как используется некоторыми другими ответами. Кроме того, это не столь чисто/эффективно как первые два решения, поскольку это вызывает 100 000 повторений вместо того, чтобы обнаружить, когда повторения становятся бессмысленными.
Язык: C, Символьное количество: 24 (обман )
main(){puts("3.14159");}
не работает с количествами цифры> 6, все же.
Haskell
я свалил его к 34 символам:
foldl subtract 4$map(4/)[3,5..9^6]
Это выражение уступает 3.141596416935556, когда оценено.
Редактирование: вот несколько более короткая версия (в 33 символах), который использует foldl1 вместо foldl:
foldl1 subtract$map(4/)[1,3..9^6]
Редактирование 2: 9^6 вместо 10^6. Нужно быть экономичным;)
Редактирование 3: Замененный foldl' и foldl1' с foldl и foldl1 respectively— в результате Редактирования 2, это больше не переполняется. Благодаря ShreevatsaR для того, чтобы замечать это.
23 символа в MATLAB:
a=1e6;sum(4./(1-a:4:a))
F#:
Попытка № 1:
let pi = 3.14159
Обман? Нет, его победа со стилем!
Попытка № 2:
let pi =
seq { 0 .. 100 }
|> Seq.map (fun x -> float x)
|> Seq.fold (fun x y -> x + (Math.Pow(-1.0, y)/(2.0 * y + 1.0))) 0.0
|> (fun x -> x * 4.0)
не столь компактный, как это могло возможно добраться, но довольно идиоматический F#.
(loop for i from 1 upto 4e5 by 4 sum (/ 8d0 i (+ i 2)))
NSum[8/i/(i+2),{i,1,9^9,4}]
при удалении начальной буквы "N" тогда она дает ответ как (огромную) часть.
, Если это обманывает тот Mathematica, не нуждается в операторе печати для вывода его результата, тогда предварительно ожидают" Print@
" для в общей сложности 33 символов.
, Если это обманывает к hardcode количество условий, тогда я не думаю, что любой ответ все же разобрался в этом. Проверка, когда текущий термин ниже некоторого порога, является не лучше, чем жесткое кодирование количеством условий. Просто, потому что текущий термин только изменяется, 6-я или 7-я цифра не означает, что сумма достаточного количества последующих условий не изменит 5-ю цифру.
Используя формулу для остаточного члена в переменном ряду (и таким образом необходимое количество повторений для достижения желаемой точности трудно не кодируется в программу):
public static void Main(string[] args) {
double tolerance = 0.000001;
double piApproximation = LeibnizPi(tolerance);
Console.WriteLine(piApproximation);
}
private static double LeibnizPi(double tolerance) {
double quarterPiApproximation = 0;
int index = 1;
double term;
int sign = 1;
do {
term = 1.0 / (2 * index - 1);
quarterPiApproximation += ((double)sign) * term;
index++;
sign = -sign;
} while (term > tolerance);
return 4 * quarterPiApproximation;
}
C#:
public static double Pi()
{
double pi = 0;
double sign = 1;
for (int i = 1; i < 500002; i += 2)
{
pi += sign / i;
sign = -sign;
}
return 4 * pi;
}
Ruby, 41 символ (использующий irb):
s=0;(3..3e6).step(4){|i|s+=8.0/i/(i-2)};s
Или это немного дольше, non-irb версия:
s=0;(3..3e6).step(4){|i|s+=8.0/i/(i-2)};p s
Это - измененный Leibniz:
(интерактивный режим) F# (59 Символов)
{0.0..1E6}|>Seq.fold(fun a x->a+ -1.**x/(2.*x+1.))0.|>(*)4.
(Урожаи предупреждение, но опускает броски)
C# с помощью блока итератора:
static IEnumerable<double> Pi()
{
double i = 4, j = 1, k = 4;
for (;;)
{
yield return k;
k += (i *= -1) / (j += 2);
}
}
Вот решение в MUMPS.
pi(N)
N X,I
S X=1 F I=3:4:N-2 S X=X-(1/I)+(1/(I+2))
Q 4*X
Параметр N указывает сколько повторных частей для использования. Таким образом, если Вы передадите в 5, то это оценит 4 * (1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11)
, Некоторое эмпирическое тестирование показало, что N=272241 является самым низким значением, которое дает правильное значение 3,14159, когда усеченный к 5 десятичным точкам. Необходимо перейти к N=852365 для получения значения, которое округляется к 3,14159.
Для записи эта реализация Схемы имеет 95 символов, игнорирующих ненужный пробел.
(define (f)
(define (p a b)
(if (> a b)
0
(+ (/ 1.0 (* a (+ a 2))) (p (+ a 4) b))))
(* 8 (p 1 1e6)))
JavaScript:
a=0,b=-1,d=-4,c=1e6;while(c--)a+=(d=-d)/(b+=2)
В JavaScript. 51 символ. Очевидно, не собираясь побеждать, но а.: Редактирование P
- обновленный, чтобы быть 46 символами теперь, благодаря Strager.:)
<час>ОБНОВЛЕНИЕ (30 марта 2010)
А быстрее (точный [только 114] к 5 десятичным разрядам) 43 символьных версии David Murdoch
for(a=0,b=1,d=4,c=~4e5;++c;d=-d)a-=d/(b-=2)
Perl:
$i+=($_&1?4:-4)/($_*2-1)for 1..1e6;print$i
для в общей сложности 42 символов.