python不是用来处理整数溢出的吗?

Posted

技术标签:

【中文标题】python不是用来处理整数溢出的吗?【英文标题】:Is python not made to handle integer overflows? 【发布时间】:2019-09-16 17:20:14 【问题描述】:

所以,我正在尝试一个编程难题,即 -> (虽然,这个难题是什么,与我的问题无关,但如果在某些情况下需要)

给你一个只读数组,包含从 1 到 n 的 n 个整数。

每个整数只出现一次,除了出现两次的 A 和缺失的 B。

返回 A 和 B。

我尝试使用与以下 C++ 代码相同的逻辑(仅进行语法更改)在 Python-3 中实现代码。

vector<int> Solution::repeatedNumber(const vector<int> &A) 

    long long int act_sum = 0;
    long long int act_sum_sq = 0;
    long long int exp_sum;
    long long int exp_sum_sq;
    long long int i = 0;

    for(i = 0; i < A.size(); i++)
        act_sum = act_sum + (long long int)A[i];
        act_sum_sq = act_sum_sq + (long long int)A[i]*A[i];
    

    exp_sum = (long long int)(A.size())*(A.size()+1)/2;
    exp_sum_sq = (long long int)(A.size())*(A.size()+1)*(2*A.size()+1)/6;

    long long int diff_sum_sq = exp_sum_sq - act_sum_sq;
    long long int diff_sum = exp_sum - act_sum;

    long long int tog = diff_sum_sq/diff_sum;

    long long int mis = (tog + diff_sum)/2;
    long long int rep = mis - diff_sum;

    vector<int> sol;
    sol.push_back((int)rep);
    sol.push_back((int)mis);

    return sol;

Python 代码 ->

class Solution:
    # @param A : tuple of integers
    # @return a list of integers

    def repeatedNumber(self, A):
         act_sum = 0
         act_sum_sq = 0
         exp_sum=0
         exp_sum_sq=0
         i = 0
         size=len(A)

         for i in range(size):
            act_sum = act_sum + A[i]
            act_sum_sq = act_sum_sq + A[i]*A[i]


         exp_sum = (size)*(size+1)/2
         exp_sum_sq =(size)*(size+1)*(2*size+1)/6

         diff_sum_sq = exp_sum_sq - act_sum_sq
         diff_sum = exp_sum - act_sum

         tog = diff_sum_sq/diff_sum

         mis = (tog + diff_sum)/2
         rep = mis - diff_sum



         return [int(rep),int(mis)]

用 python 编写的代码在挑战网站上给出了部分正确的答案,(它给出了代码在较大的测试用例中可能失败的原因——比如数组中有大约 2000 个元素) 但, C++ 中的相同代码(仅进行语法更改)绝对可以正常工作! 为什么? 那么,C++ 中 long long int 的存在会是这背后的原因吗? python 不是用于庞大的数据集吗?如果没有,那么如何在python中处理溢出

【问题讨论】:

Python 整数可以是任意大小,如果您愿意,甚至可以达到一千字节。请发布您的 Python 代码。 我有点困惑。您的问题是否可能只是“python如何处理整数溢出?”在 c++ 中签名溢出是未定义的,所以我真的不明白你关于代码在 c++ 中“很好”的结论 还要注意unsigned long long int 可以容纳的正数大约是long long int 的两倍。 不要将代码从一种语言移植到另一种语言。它很少起作用。 It doesn't even work for human communication languages. 语言可能看起来相似,但它们的行为不同。您需要做的是了解程序所描述的行为,并根据该语言的规则和习语在新语言中实现相同的行为。 由于您使用的是signed 整数,如果有任何溢出,您将有未定义的行为。它可能有效,也可能无效,并且可能会在没有明显原因的情况下随时更改。 【参考方案1】:

您的问题在于以下几行:

exp_sum = (long long int)(A.size())*(A.size()+1)/2;
exp_sum_sq = (long long int)(A.size())*(A.size()+1)*(2*A.size()+1)/6;

对比

exp_sum = (size)*(size+1)/2
exp_sum_sq =(size)*(size+1)*(2*size+1)/6

C++ 版本中exp_sum 的类型为long long int。在 python 中它是 float(相当于 C++ double)。 python中的转换发生在分区中。 python3中的正常除法always returns a float。您可以改用这些行来修复您的 python 代码:

exp_sum =  size * (size + 1) // 2
exp_sum_sq =  size * (size + 1) * (2 * size + 1) // 6

通过此修复,python 版本应该没有更多限制 - 与 C++ 不同,python 整数可以保存任意大的值并且永远不会溢出。

【讨论】:

以上是关于python不是用来处理整数溢出的吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中处理整数溢出的最佳方法?

由于 Objective-C 中的整数溢出,处理和报告内存分配错误的最佳方法是啥?

漏洞预警| Google Chrome处理 WebAssembly Locals 时存在整数溢出漏洞

poi导出大数据,报内存溢出怎么解决

数学与数字3:整数反转-溢出的统一处理法则

Python异常处理