Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why java stream sum api returns the sum in same data type and not a bigger one?

I have some integers which I am adding using Arrays.stream(int arr[]).sum(). It returns the truncated sum in int while the actual sum is bigger and fits in long. why does the stream API returns only int by truncating it but not long?

Tried for small integers like int myArray[] = { 1, 5, 8 }; int sum = Arrays.stream(myArray).sum();

works fine.

but doesn't work for longer integers whose sum leads to long.

Scenario 1 below works fine and returns 14

int myArray[] = { 1, 5, 8 };
int sum = Arrays.stream(myArray).sum();

while scenario 2 won't work as sum is going beyond 32 bits. it gives sum as -105032716 while expected is 4189934580

int myArray[] = { 2094967290, 2094967290};
int sum = Arrays.stream(myArray).sum();

and to get the correct sum, if I do below I get the expected result 4189934580

long sum = 0L + 2094967290+2094967290;
System.out.println(sum);
like image 404
Venkatesh Kolla - user2742897 Avatar asked Jun 07 '26 03:06

Venkatesh Kolla - user2742897


2 Answers

This is something that's up to the developer. You know what to expect, what data you're dealing with, and, more importantly, you test it. In my opinion, this is not different from how we handle the possible overflow of any intOne + intTwo.

If you know that the sum will exceed the int range, then switch to a long stream (thanks to Carlos Heuberger for asLongStream() instead of mapToLong(i -> i)):

long sum = Arrays.stream(myArray).asLongStream().sum();
like image 62
ernest_k Avatar answered Jun 10 '26 19:06

ernest_k


You are summing int(s) (a 32-bit primitive data type). If you want a long, sum long(s). This is how primitive math works.

int c = 2094967290 + 2094967290;
System.out.println(c);

is the same as

System.out.println(2094967290 + 2094967290);

Using long(s)

System.out.println(2094967290 + 2094967290L);

or with streams like this will yield the correct result here

long sum = Arrays.stream(myArray).mapToLong(Long::valueOf).sum();

or (as pointed out in the comments)

long sum = Arrays.stream(myArray).asLongStream().sum();

However, long can also overflow (it is a 64-bit primitive data type). For arbitrary precision, you should use BigInteger.

BigInteger sum = Arrays.stream(myArray).mapToObj(BigInteger::valueOf)
        .reduce(BigInteger.ZERO, (a, b) -> a.add(b));
like image 27
Elliott Frisch Avatar answered Jun 10 '26 18:06

Elliott Frisch



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!