У меня были некоторые проблемы с куском кода и в итоге я сделал следующий фрагмент командной строки. Это был просто эксперимент, и я не хранил такие большие значения в любой переменной в реальном коде (по модулю 10 ** 9 +7).,
>>> a=1
>>> for i in range(1,101):
... a=a*i
...
>>> b=1
>>> for i in range(1,51):
... b=b*i
...
>>> c=pow(2,50)
>>> a//(b*c)
2725392139750729502980713245400918633290796330545803413734328823443106201171875
>>> a/(b*c)
2.7253921397507295e+78
>>> (a//(b*c))%(10**9 +7)
196932377
>>> (a/(b*c))%(10**9 +7)
45708938.0
>>>
Я не понимаю, почему integer divison дает правильный результат, в то время как сбрасывание с плавающей запятой терпит неудачу.
В основном я вычислил: ( (100!)/((50!)*(2^50)) ) % (10**9 +7)
Из-за точности.
Целые числа и поплавки кодируются по-разному. В частности, в python 3 целые числа могут быть сколь угодно большими - то, которое вы дали, например, больше 250 бит, когда вы конвертируете его в двоичный. Они хранятся таким образом, который может приспосабливаться, насколько они велики.
Однако числа с плавающей запятой ограничены определенным размером - обычно 64 бит. Эти 64 бита делятся на знак (1 бит), мантисса и экспонента - количество бит в мантиссе ограничено, насколько точным может быть число. Документация Python содержит раздел об этом ограничении.
Итак, когда вы это делаете
(a//(b*c))%(10**9 +7)
вы выполняете этот расчет с целыми числами, которые, опять же, сколь угодно велики. Однако, когда вы это делаете:
(a/(b*c))%(10**9 +7)
вы выполняете этот расчет с числом, которое имеет только 18 значащих цифр - оно уже неточно, и выполнение большего количества вычислений с ним только еще больше развращает ответ.
Что бы вы могли сделать, чтобы избежать этого, если вам нужно использовать очень большие числа с плавающей запятой, используется десятичный модуль python (который является частью стандартной библиотеки), который не будет иметь этих проблем.
Причина в том, что целые числа точны, но поплавки ограничены точностью с плавающей запятой: точность поплавка по умолчанию Python2.7
5529771903
округленное до пяти значащих цифр, будет 5529700000
.
mpmath
который поддерживает выполнение арифметики с плавающей точкой произвольной точности.