Как получить значение 0,5^(5000) в Python3?

#python #python-3.x #numeric #largenumber

Вопрос:

Текущее значение, которое я хочу рассчитать a=0.5**5000 . Я знаю a , что это очень маленькое значение , но мне нужно использовать a для умножения b , где b = 5000! очень большое значение.

Но когда я вычисляю значение a=0.5^5000 , результат равен 0. У кого-нибудь есть хороший метод решения этой проблемы? Спасибо!

Комментарии:

1. Вы имеете в виду под a = 0.5 * 5000 этим ??

2. ибо .5 ** 5000 это, вероятно, возвращается 0.0 , потому что плавающие элементы python не могут показать такую точность (число слишком близко к нулю, чтобы python мог отличить его от 0). Самое низкое, что вы получите с pure python в .5 ** 1074

3. Вы можете выяснить, какова наибольшая степень двойки, которая делит 5000! а затем выясните в закрытой форме, какая степень двойки остается после умножения на 0,5**5000. justquant.com/numbertheory/. … Поскольку это, скорее всего, упражнение, возможно, смысл в том, чтобы подумать о способах вычисления ответа без чистой грубой силы.

4. Вам нужно n!/(2**n) , или вы умножите это на другое число? Вероятно, есть лучший способ вычислить это. Например, n choose k есть n!/((n-k)!*k!) , но никто не вычисляет его таким образом; вы вычисляете его рекурсивно с ((n-1) choose k) ((n-1) choose (k-1)) помощью .

5. Не могли бы вы, пожалуйста, пояснить, зачем вам это нужно? Конечно, вас не интересует фиксированное значение 5000! * 0,5^5000 но какая-то параметризованная формула для вычисления чего-то практического?

Ответ №1:

Мне нужно использовать a , чтобы размножаться b , где b = 5000!

Я бы просто поделил 5000! на 2 5000 или сдвиньте его:

 from math import factorial

print(factorial(5000) // 2**5000)
print(factorial(5000) >> 5000)
 

Выход:

 299375336...(more than 14000 digits)...080261230
 

Или, как указывает @wim, fractions.Fraction было бы точно:

 print(Fraction(factorial(5000), 2**5000))
 

Выход:

 958001075...(more than 14000 digits)...568359375/32
 

Который в десятичной системе счисления является:

 299375336...(more than 14000 digits)...080261230.46875
 

Таким образом, в данном случае это дает нам только еще пять цифр точности, не намного больше по сравнению с уже более чем 14000. Но, например, для 5!/2 5 это будет 3,75 вместо 3, довольно большая разница. Опять же, это небольшое число (если вы его также используете) может быть незначительным в том, что вы делаете в целом. Чего мы не знаем, потому что вы рассказали нам только об этой крошечной части вашей попытки сделать то, что вам на самом деле нужно.

Комментарии:

1. Результат на самом деле не является целым числом, поэтому использование // теряет точность.

2. @wim Он содержит 14821 цифру точности. Почему ты думаешь, что этого недостаточно? Это намного больше, чем дают другие ответы.

3. Да, я думаю, этого недостаточно. Когда речь идет о факториалах, это часто какое-то математическое приложение, в котором вам действительно нужна точная арифметика, так почему бы не использовать Fraction(*divmod(factorial(5000), 2**5000)) вместо усечения // .

4. @wim Мой faaaaar более точен, чем ваш Fraction(*divmod(factorial(5000), 2**5000)) . Понятия не имею, зачем ты там делаешь divmod :-П. Но да, правильная дробь была бы еще более точной. Почему я этого не сделал? Не видел в этом необходимости. И теперь, когда ОПЕРАЦИЯ приняла гораздо менее точное решение, я все еще этого не делаю.

5. Тьфу, я пытался сжать его на одной строке, но напортачил. q, r = divmod(factorial(5000), 2**5000) тогда q это ваш результат, а r это остаток, так что точный результат q Fraction(r, 2**5000) (упрощается до Fraction(15, 32) интересного!).

Ответ №2:

Попробуйте десятичный модуль:

 >>> from decimal import Decimal
>>> print(Decimal("0.5") ** 5000)
7.079811261048172892385615159E-1506
>>> 
 

Ответ №3:

Вот альтернативный ответ с использованием библиотеки mpmath:

 import mpmath

a = mpmath.power(0.5, 5000)
b = mpmath.factorial(5000)
c = mpmath.fmul(a, b)

print(a)
print(b)
print(c)
 

Это включает в себя другие расчеты, о которых вы упомянули.

Выход:

 7.0798112610481728923856151586941e-1506
4.2285779266055435222010642002336e 16325
2.9937533623001661362907254353912e 14820
 

Ответ №4:

Используйте десятичную дробь :

 from decimal import Decimal

if __name__ == '__main__':
    a = Decimal(str(0.5)) ** Decimal(str(5000))
    print(a)

7.079811261048172892385615159E-1506
 

Комментарии:

1. При использовании Decimal вы должны передавать строку , а не a float . Этот поплавок работает правильно, но вы не должны этого делать.

2. затем проанализируйте float в строку, но почему я не должен этого делать ?

3. Нет . Не делай этого, передай строку . Посмотри, что происходит Decimal(0.1) . И полагаться str -значит полагаться на детали реализации

4. Если вы не можете преобразовать в строку, как вы можете вычислить динамические значения?

5. Вы должны начать со строк/десятичной дроби.