C++中std::accumulate传0和0ll作为初始值有什么区别?
关于std::accumulate初始值选择的原因解答
核心本质:std::accumulate的类型规则
std::accumulate的累加过程中间值类型、最终返回值类型,完全由第三个初始值参数的类型决定,和你最终赋值的变量类型无关:
- 当你传入
0作为初始值时,它的类型是int,累加全程都按照int类型计算,所有中间结果都是int,直到最后计算完成后,才会将最终的int值赋值给你定义的long long sum变量。 - 当你传入
0ll作为初始值时,它的类型是long long,累加过程每一步都是long long类型计算,中间结果全程都是64位整数,不会出现提前溢出的问题。
为什么你的测试结果一致
你测试时两种写法结果相同,只是因为你的测试用例中所有元素的总和没有超过int类型的上限(主流平台上int为4字节,可承载的最大值为2^31-1≈2.1e9),累加过程中没有发生溢出,两种写法的最终结果自然相同。
一旦你的元素总和超过int的上限,用0作为初始值的写法会直接在累加过程中发生整数溢出,触发C++的未定义行为,哪怕最后赋值给long long变量,得到的也已经是溢出后的错误结果,没有办法挽回。
推荐使用0ll的原因
实际开发中数组的规模、元素大小都不可控,int类型的上限很容易被突破:比如你有1e5个元素,每个元素值为1e5,总和就是1e10,远超过int的承载范围。使用0ll作为初始值,可以从根源上保证累加过程全程使用64位整数计算,完全避免中间溢出的风险,代码的鲁棒性更高。
内容的提问来源于stack exchange,提问作者Showyeab Ahmed
相关产品推荐
相关产品推荐

