这个python代码
for x in range(20, 50): print(x,math.factorial(x),math.pow(2,x), math.factorial(x) % math.pow(2,x) )计算精确到x = 22但是当x> 22时的mod总是0。
Wolframalpha说x> 22的结果是非零的。 例如,当x = 23时,我们得到6815744。
我想这个问题是由python如何实际计算mod函数引起的,但是想知道是否有人真正知道。
This python code
for x in range(20, 50): print(x,math.factorial(x),math.pow(2,x), math.factorial(x) % math.pow(2,x) )calculates fine up to x=22 but the mod when x>22 is always 0.
Wolframalpha says the results for x>22 are nonzero. For example, when x=23 we get 6815744.
I guess this problem results from how python actually calculates the mod function but was wondering if anyone actually knew.
最满意答案
您遇到了浮点限制; math.pow()返回一个浮点数,因此两个操作数都被强制转换为浮点数。 对于x = 23 , math.factorial(x)返回一个大于float可以建模的整数:
>>> math.factorial(23) 25852016738884976640000 >>> float(math.factorial(23)) 2.585201673888498e+22右侧算子是一个小得多的浮点数(只有7位数),指数的差异导致模数运算符错误输出。
使用**坚持整数:
for x in range(20, 50): print(x, math.factorial(x), 2 ** x, math.factorial(x) % (2 ** x))整数运算仅限于可用的内存量,对于x = 23 ,计算正确的值,继续正常工作到x = 49 :
>>> x = 23 >>> print(x, math.factorial(x), 2 ** x, math.factorial(x) % (2 ** x)) 23 25852016738884976640000 8388608 6815744 >>> x = 49 >>> print(x, math.factorial(x), 2 ** x, math.factorial(x) % (2 ** x)) 49 608281864034267560872252163321295376887552831379210240000000000 562949953421312 492581209243648请注意,即使对于较小的浮点模数计算,您也应该使用math.fmod()函数 ,原因在文档中有解释。 然而,这种情况也失败了,因为你超越了浮点数学的极限:
>>> print(x, math.factorial(x), math.pow(2, x), math.fmod(math.factorial(x), math.pow(2, x))) 23 25852016738884976640000 8388608.0 0.0You are running into floating point limitations; math.pow() returns a floating point number, so both operands are coerced to floats. For x = 23, math.factorial(x) returns an integer larger than what a float can model:
>>> math.factorial(23) 25852016738884976640000 >>> float(math.factorial(23)) 2.585201673888498e+22The right-hand-side operator is a much smaller floating point number (only 7 digits), it is that difference in exponents that causes the modulus operator error out.
Use ** to stick to integers:
for x in range(20, 50): print(x, math.factorial(x), 2 ** x, math.factorial(x) % (2 ** x))Integer operations are only limited to how much memory is available, and for x = 23 the correct value is calculated, continuing to work correctly all the way to x = 49:
>>> x = 23 >>> print(x, math.factorial(x), 2 ** x, math.factorial(x) % (2 ** x)) 23 25852016738884976640000 8388608 6815744 >>> x = 49 >>> print(x, math.factorial(x), 2 ** x, math.factorial(x) % (2 ** x)) 49 608281864034267560872252163321295376887552831379210240000000000 562949953421312 492581209243648Note that for even for smaller floating point modulus calculations, you really should be using the math.fmod() function, for reasons explained in the documentation. It too fails for this case however, again because you are reaching beyond the limits of floating point math:
>>> print(x, math.factorial(x), math.pow(2, x), math.fmod(math.factorial(x), math.pow(2, x))) 23 25852016738884976640000 8388608.0 0.0更多推荐
发布评论