5

For example we have an int array:

var array = new int[]{ 2147483647, 2147483647, 2147483647, 2147483647};

What is the easiest way to calculate the sum of the array entries, BUT in respect to the example provided above?

array.Sum()

results in:

Arithmetic operation resulted in an overflow

Because the result is not an int anymore..

Legends
  • 21,202
  • 16
  • 97
  • 123

3 Answers3

15

Because the sum of the values in your array overflows the Int32.MaxValue you are forced to cast your elements to a long

var array = new int[]{ 2147483647, 2147483647, 2147483647, 2147483647};
var total = array.Sum(x => (long)x);
Console.WriteLine(total);

And you can see that the total variable is of type Int64

Console.WriteLine(total.GetType());
Steve
  • 213,761
  • 22
  • 232
  • 286
8

Steve's answer fits your question perfectly. However, if you need to store the sum of values that are longer than the typical datatypes you could use BigInteger.

var array = new [] { long.MaxValue, long.MaxValue, long.MaxValue, long.MaxValue };
var result = new BigInteger();
result = array.Aggregate(result, (current, i) => current + i);

This solution would also work for your provided array.

Matt Rowland
  • 4,575
  • 4
  • 25
  • 34
  • Well, someone here seems to disagree on providing help. – Steve Jan 06 '17 at 22:36
  • Decimal type can also be used to sum arrays of long[], as in `var total = array.Sum(x => (decimal)x);` which benchmarks about 5X faster than BigInteger. To go even faster `var total = array.AsParallel().Sum(x => (long)x); To go even faster still HPCsharp nuget package has .Sum() functions that use data parallel SSE instructions and use mutli-core parallelism as well. – DragonSpit Jul 22 '19 at 02:41
  • @DragonSpit You are welcome to add your answer to the question. Keep in mind, my answer was meant to supply a way to achieve the desired result with numbers that the typical datatypes cannot handle. `Decimal` would fall into the category of typical as it has upper bounds. – Matt Rowland Jul 22 '19 at 02:57
1

To expand on Steve's solution to "How to sum a long[] array which exceeds Int64.MaxValue?", decimal type can be used to sum arrays of long[], as:

var array = new [] { long.MaxValue, long.MaxValue, long.MaxValue, long.MaxValue };
var result = array.Sum(x => (decimal)x);

decimal has a 96-bit mantissa, which is sufficient for a perfectly accurate result of an array with 2 Giga longs in it, which is the maximum size of an array in C# due to array index being limited to an Int32. Using the above decimal implementation is 5X faster than using BigInteger.

To go even faster:

result = array.AsParallel().Sum(x => (decimal)x);

this solution takes advantage of multi-core CPU for additional performance.

To go even faster, HPCsharp nuget package implements Sum() for int[], uint[], long[], ulong[] and all of the other signed and unsigned integers types, using data parallel SSE instructions, for faster performance on a single core, as well as parallel multi-core, while dealing with the sum exceeding MaxValue for each data type.

DragonSpit
  • 458
  • 4
  • 9