1 回答
TA贡献1862条经验 获得超6个赞
我想给出一个奢侈的 ;-) 答案,但现在没有时间。详细说明我的评论,该decimal模块是您真正想要的。计算功率要快得多 ,将结果转换为十进制字符串要快得多:
>>> import decimal
您需要更改其内部结构以避免使用浮点数,从而为其提供足够多的内部数字来存储最终结果。我们在这里需要精确的整数运算,而不是四舍五入的浮点数。所以我们摆弄东西,decimal尽可能使用它能够使用的精度,并告诉它在舍入时丢失信息时引发“不精确”异常。请注意,您需要 64 位版本的 Pythondecimal才能使用足够的精度来保存示例中的确切结果:
>>> import decimal
>>> c = decimal.getcontext()
>>> c.prec = decimal.MAX_PREC
>>> c.Emax = decimal.MAX_EMAX
>>> c.Emin = decimal.MIN_EMIN
>>> c.traps[decimal.Inexact] = 1
现在为基础创建一个Decimal:
>>> base = decimal.Decimal(12345678901234567890123456)
>>> base
Decimal('12345678901234567890123456')
并提高幂 - 指数将自动转换为Decimal,因为基数已经是Decimal:
>>> x = base ** 12345678
这在我的盒子上只需要不到一分钟!其中的原因是有的。这并不是因为它以 10 为底,而是因为编写该decimal模块的人实现了“高级”算法来进行非常大的乘法运算。
现在转换为字符串。因为它已经存储在以 10 为底的变体中,所以转换为十进制字符串非常快(在我的盒子上几秒钟,因为字符串有数亿位数字):
>>> y = str(x)
>>> len(y)
309771765
而且,为了理智,让我们看看最后 10 位和前 10 位数字:
>>> y[-10:]
'6044706816'
>>> y[:10]
'2759594879'
正如@StefanPochmann 在评论中指出的那样,通过使用模块化(3-argument),可以使用本机整数非常快速地获得最后 10 位数字pow():
>>> pow(int(base), 12345678, 10**10)
6044706816
匹配上面字符串的最后 10 位数字。对于前 10 位数字,我们可以decimal再次使用,但精度要低得多,这将导致它(你相信我)在幕后使用不同的方法:
>>> c.prec = 12
>>> c.traps[decimal.Inexact] = 0 # don't trap on rounding!
>>> base ** 12345678
Decimal('2.75959487945E+309771764')
将其四舍五入到 10 位与之前的结果相匹配,并且指数也与 的长度一致y。
添加回答
举报