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不是用来处理整数溢出的吗?的主要内容,如果未能解决你的问题,请参考以下文章
由于 Objective-C 中的整数溢出,处理和报告内存分配错误的最佳方法是啥?