热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python中可能的整数溢出

如何解决《python中可能的整数溢出》经验,为你挑选了1个好方法。



1> Martijn Piet..:

您正在使用浮点除法,其中整数除法将执行:

int((n-1)/3.0)

更好地表达为

(n-1)//3

例如,使用Python的分区操作员,不要使用浮点数,然后使用地板.

使用整数分区不会遇到舍入问题,因为您将浮点运算拉伸超出其限制.

当你推n得足够大时,你可以看到这个舍入错误:

>>> n = 100000000
>>> int((int((n-1)/15.0)+1) * (int((n-1)/15.0)/2.0) * 15)
333333316666665
>>> ((n-1)//15+1) * ((n-1)//15//2) * 15
333333316666665
>>> n = 1000000000
>>> int((int((n-1)/15.0)+1) * (int((n-1)/15.0)/2.0) * 15)
33333333166666664
>>> ((n-1)//15+1) * ((n-1)//15//2) * 15
33333333166666665

额外的1来自于你遇到浮动的极限这一事实:

>>> (int((n-1)/15.0)+1) * (int((n-1)/15.0)/2.0)
2222222211111111.0
>>> ((n-1)//15+1) * ((n-1)//15//2)
2222222211111111
>>> (int((n-1)/15.0)+1) * (int((n-1)/15.0)/2.0) * 15
3.3333333166666664e+16

我不确定你为什么要减去一个n; 这根本不需要,导致不正确的结果.也许你试图弥补浮动舍入错误?正确的公式是:

(((n // 3) + 1) * (n // 3)) // 2 * 3
(((n // 5) + 1) * (n // 5)) // 2 * 5
(((n // 15) + 1) * (n // 15)) // 2 * 15

给我任何正确的输出n:

>>> n = 1000000000
>>> sum_of_multiples_3 = (((n // 3) + 1) * (n // 3)) // 2 * 3
>>> sum_of_multiples_5 = (((n // 5) + 1) * (n // 5)) // 2 * 5
>>> sum_of_multiples_15 = (((n // 15) + 1) * (n // 15)) // 2 * 15
>>> sum_of_multiples_3 + sum_of_multiples_5 - sum_of_multiples_15
233333334166666668

我在这里使用了一个函数来计算倍数:

def sum_of_multiples(n, k):
    k_in_n = n // k
    return ((k_in_n + 1) * k_in_n) // 2 * k

所以你可以通过比较蛮力总和来验证它是否有效:

>>> sum(range(0, 10000 + 1, 3)) == sum_of_multiples(10000, 3)
True
>>> sum(range(0, 10000 + 1, 5)) == sum_of_multiples(10000, 5)
True
>>> sum(range(0, 10000 + 1, 15)) == sum_of_multiples(10000, 15)
True

然后用它来计算答案:

>>> sum_of_multiples(n, 3) + sum_of_multiples(n, 5) - sum_of_multiples(n, 15)
233333334166666668


推荐阅读
author-avatar
大脸猫妈妈-啊珍妮妮_786
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有