#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
вы должны передавать строку , а не afloat
. Этот поплавок работает правильно, но вы не должны этого делать.2. затем проанализируйте float в строку, но почему я не должен этого делать ?
3. Нет . Не делай этого, передай строку . Посмотри, что происходит
Decimal(0.1)
. И полагатьсяstr
-значит полагаться на детали реализации4. Если вы не можете преобразовать в строку, как вы можете вычислить динамические значения?
5. Вы должны начать со строк/десятичной дроби.