ZeroDivsionError с факториалом в python

Я получаю ноль, когда запускаю код

факториал(nx)*факториал(x)

Это мой первый вопрос в stackoverflow.

ниже мои коды

def factorial(x):
    res = 1

    if x==0:
        return 1
    
    while x>0:
        res*=x
        x-=1
    return res

def combination(n,x):
    return factorial(n)/(factorial(n-x)*factorial(x))

def binomial(n,x,p):
    return combination(n,x)*(p**x)*((1-p)**(n-x))

pmf_values = []

n=200
x_list = np.arange(0,200+1)

for x in x_list:
    #print(x)
    #print((factorial(n-x)*factorial(x)))
    pmf_values.append(binomial(n,x,p))

sample = np.random.choice(
    x_list,size=10000,p=pmf_values)
plt.hist(sample)

Я обнаружил, что ошибка возникает, когда x равен 0. когда я запускаю его в отдельной ячейке, он возвращает правильный ответ 1.0

Странно, что он нормально работает в отдельной ячейке но возвращает ошибку в цикле

Спасибо за помощь

Что означает "запустить его в отдельной ячейке"?

Scott Hunter 14.05.2023 03:03

Добро пожаловать в Stack Overflow. Ваш вопрос на самом деле довольно хорошо структурирован, но ваш код не воспроизводится. Пожалуйста, не просто копируйте и вставляйте свой существующий код, а вместо этого начните с нуля и создайте минимально воспроизводимый пример, который другие люди смогут запускать без проблем.

SimonUnderwood 14.05.2023 03:05

В pmf_values.append(binomial(n,x,p))p не определено.

Scott Hunter 14.05.2023 03:06

Пара комментариев по поводу factorial: (1) Особый случай для x == 0 совершенно не нужен. Просто удалите его. Цикл while будет пропущен, когда x будет равен нулю, и вы провалитесь и вернетесь 1, как и предполагалось. Не придумывайте ненужные частные случаи. И (2) Вам не нужен собственный факториал. Вы можете просто использовать math.factorial. Кроме того, если ваша версия Python 3.8 или более поздняя, ​​вы можете использовать math.comb вместо combination.

Tom Karzes 14.05.2023 03:11

спасибо всем, я опубликую свой вопрос более четко и сделаю свой код воспроизводимым в следующий раз. Я думаю, что создавать функцию с нуля было плохой идеей.

Junho65 16.05.2023 14:54
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
5
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я также получил нули, используя вашу факториальную функцию. Это странно. (Питон 3.10.10).

Я распечатал выводы:

factorial(135)*factorial(65)
0*-9223372036854775808=0
factorial(134)*factorial(66)
0*0=0
...
factorial(66)*factorial(134)
0*0=0
factorial(65)*factorial(135)
-9223372036854775808*0=0
...
factorial(23)*factorial(177)
8128291617894825984*0=0
factorial(22)*factorial(178)
-1250660718674968576*0=0
factorial(21)*factorial(179)
-4249290049419214848*0=0
factorial(20)*factorial(180)
2432902008176640000*0=0

Возврат факториала начал колебаться от отрицательного/положительного выше факториала (20) и пошел к нулю, начиная с факториала (66).

Попробуйте это, это сработало для меня и в любом случае выглядит лучше:

def factorial(x):
  res = 1 
  for i in range(2,x+1):
    res *= i
  return res 

Редактировать:

Я заставил его работать, используя вашу исходную факториальную функцию:

def factorial(x):
  x = int(x)
  res = 1
  while x > 1:
    res *= x
    x -= 1
  return res

Итак, это проблема переполнения с numpy. Передаваемый x исходит от np.arange()

Причина, по которой моя более короткая функция сработала, заключается в том, что между numpy int64 никогда не бывает математики, и если вы преобразуете x в Python int до того, как выполните математику, это также сработает. В противном случае тип numpy int64 переполнится.

https://numpy.org/doc/stable/user/basics.types.html#overflow-errors

$ pip freeze | grep numpy
numpy==1.24.3

большое спасибо за ваш добрый ответ. Я не был знаком с numpy, ваш ответ мне очень помог

Junho65 16.05.2023 15:05

Другие вопросы по теме