long long仍溢出:求1到n符号交替数列和问题(n≤1e15)
问题分析与解决
原代码的问题
你的代码存在两个核心问题导致溢出和计算错误:
- 浮点数精度丢失:使用
/4.0将整数除法转为浮点数运算,当n接近1e15时,double类型无法精确表示这么大的整数,会导致计算结果出现误差,转成long long时进一步放大错误。 - 整数乘法溢出:比如计算
(n-1)*(2+(n-1))时,n=1e15的情况下,两个因子都接近1e15,乘积会达到1e30,远超64位long long的最大值(约9e18),直接溢出导致结果错误。
简化数学公式
观察数列规律可以直接推导更简洁的求和公式,完全避免复杂运算:
- 当n为偶数时:每两项的和为
-k + (k+1) = 1,共n/2组,总和为n/2 - 当n为奇数时:前n-1项(偶数项)的和为
(n-1)/2,加上最后一项-n,总和为(n-1)/2 - n = -(n+1)/2
修正后的代码
#include <iostream> using namespace std; int main() { long long n; cin >> n; long long sum; if (n % 2 == 0) { sum = n / 2; } else { sum = -(n + 1) / 2; } cout << sum << endl; return 0; }
为什么不会溢出?
- 对于n≤1e15,
n/2和(n+1)/2的结果最大为5e14+0.5,转为long long后是5e14,远小于long long的上限9e18,完全不会出现溢出问题。 - 全程使用整数运算,没有浮点数精度损失,计算结果绝对准确。
内容的提问来源于stack exchange,提问作者Mohammad AK 55
相关产品推荐
相关产品推荐

