繁体   English   中英

n ** n ** n启发式Python

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM