例如,我们有一个int数组:
var array = new int[]{ 2147483647, 2147483647, 2147483647, 2147483647};
计算数组条目总和的最简单方法是什么,但就上面提供的示例而言?
array.Sum()
结果:
算术运算导致溢出
因为结果不再是int ..
答案 0 :(得分:11)
因为数组中的值总和溢出Int32.MaxValue
,您将被迫将元素强制转换为长
var array = new int[]{ 2147483647, 2147483647, 2147483647, 2147483647};
var total = array.Sum(x => (long)x);
Console.WriteLine(total);
您可以看到总变量的类型为Int64
Console.WriteLine(total.GetType());
答案 1 :(得分:6)
BigInteger
。
var array = new [] { long.MaxValue, long.MaxValue, long.MaxValue, long.MaxValue };
var result = new BigInteger();
result = array.Aggregate(result, (current, i) => current + i);
此解决方案也适用于您提供的阵列。
答案 2 :(得分:1)
要扩展Steve的“如何求和一个超出Int64.MaxValue的long []数组?”的解决方案,可以使用十进制类型对long []的数组求和,如下:
class Foo<T>(val n: Int) {
// How to make this int[]?
// Or IntArray?
lateinit var data: Any
inline fun <reified T> createNullArray() {
data = arrayOfNulls<T>(n)
}
}
十进制数有一个96位尾数,这足以实现其中2 Giga长的数组的精确结果,这是C#中数组的最大大小,这是因为数组索引限制为Int32。使用上述十进制实现比使用BigInteger快5倍。
走得更快:
class Foo(val n: Int) {
lateinit var data: Any
inline fun <reified T> createNullArray() {
data = arrayOfNulls<T>(n)
}
}
该解决方案利用多核CPU的优势来提高性能。
为了更快,HPCsharp nuget包使用数据并行SSE指令为int [],uint [],long [],ulong []和所有其他有符号和无符号整数类型实现了Sum()单核以及并行多核的性能,而每种数据类型的总和都超过了MaxValue。