[英]n**n**n heuristics in Python
我只是玩Python
并发现了一件有趣的事情:我的电脑(i5,3 GHz)在试图计算10 ** 10 ** 10
几个小时后才挂出。 我知道Math不是为Python创建的目的,但我想知道是不是有办法帮助Python
计算它。
到目前为止我所观察到的是: n ** (2** lg(n**n))
比n ** n ** n
快2倍
n = 8 ** (8 ** 8)
n2 = 8 ** (2 ** 24)
# measured by timeit
> 4.449993866728619e-07
> 1.8300124793313444e-07
1)有没有人知道如何以最复杂的方式解决n ** n ** n
?
2)生成器可以帮助减少内存滥用吗?
10 ** 10 ** 10
是一个非常大的数字 。 Python正在尝试分配足够的内存来表示该数字。 10.000.000.000(100亿)位数比计算机一次性提供的内存要多得多,因此您的计算机现在将内存交换到磁盘以腾出空间,这就是为什么现在的速度非常慢。
为了说明,尝试在一些适合的数字上使用sys.getsizeof()
:
>>> import sys
>>> sys.getsizeof(10 ** 10 ** 6)
442948
>>> sys.getsizeof(10 ** 10 ** 7)
4429264
所以额外的数字需要大约 10倍的内存。 以上金额以字节为单位,因此100万位数字几乎占用半兆字节,1000万位数字占4兆字节。 在Extrapoliting中,您的号码需要4 GB的内存。 这取决于你的操作系统和硬件,如果Python甚至会给予那么多的内存。
Python在现代平台上以30位的增量存储整数; 所以每30位需要额外的4个字节的存储空间。 对于100亿个数字(log2(10 ** 10 ** 10) / 30 * 4) / (1024 ** 3)
==约4.125GiB。
你不能使用Python来表示这么大的数字。 甚至浮点数也不会达到那么高:
>>> 10.0 ** 10 ** 10
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: (34, 'Result too large')
我对Python中的bignum(大数字)处理并不熟悉; 也许gmpy
libray有能力代表更好的数字。
如果整数精度不是最重要的,则可以使用float
>>> 3**3**3
7625597484987
>>> 3.**3.**3.
7625597484987.0
但是,对于较大的值,这些将很快达到其极限:
>>> 5.**5.**5.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: (34, 'Numerical result out of range')
decimal
可以得到更高的值:
>>> import decimal
>>> d = decimal.Decimal
>>> d(5)**d(5)**d(5)
Decimal('1.911012597945477520356404560E+2184')
>>> d(10)**d(10)**d(8)
Decimal('1.000000000000000000000000000E+100000000')
默认情况下,即使是那些也不能代表10**10**10
:
>>> d(10)**d(10)**d(10)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/decimal.py", line 2386, in __pow__
ans = ans._fix(context)
File "/usr/lib/python2.7/decimal.py", line 1676, in _fix
ans = context._raise_error(Overflow, 'above Emax', self._sign)
File "/usr/lib/python2.7/decimal.py", line 3872, in _raise_error
raise error(explanation)
decimal.Overflow: above Emax
但这些限制并不固定。 使用getcontext()
可以使它们尽可能大:
>>> decimal.getcontext().Emax = 1000000000000
>>> d(10)**d(10)**d(10)
Decimal('1.000000000000000000000000000E+10000000000')
但请记住,这些数字并不是最后一位数字的100%精确度(您的计算机可能甚至没有足够的内存来存储每个数字),所以如果发生这种情况,请不要感到惊讶:
>>> d(10)**d(10)**d(10) == d(10)**d(10)**d(10) + 1000000
True
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.