Saturated addition of two signed Java 'long' values

Posted by finnw on Stack Overflow See other posts from Stack Overflow or by finnw
Published on 2010-04-13T19:01:59Z Indexed on 2010/04/13 19:03 UTC
Read the original article Hit count: 541

How can one add two long values (call them x and y) in Java so that if the result overflows then it is clamped to the range Long.MIN_VALUE..Long.MAX_VALUE?

For adding ints one can perform the arithmetic in long precision and cast the result back to an int, e.g.:

int saturatedAdd(int x, int y) {
  long sum = (long) x + (long) y;
  long clampedSum = Math.max((long) Integer.MIN_VALUE,
                             Math.min(sum, (long) Integer.MAX_VALUE));
  return (int) clampedSum;
}

or

import com.google.common.primitives.Ints;

int saturatedAdd(int x, int y) {
  long sum = (long) x + (long) y;
  return Ints.saturatedCast(sum);
}

but in the case of long there is no larger primitive type that can hold the intermediate (unclamped) sum.

Since this is Java, I cannot use inline assembly (in particular SSE's saturated add instructions.)

It can be implemented using BigInteger, e.g.

static final BigInteger bigMin = BigInteger.valueOf(Long.MIN_VALUE);
static final BigInteger bigMax = BigInteger.valueOf(Long.MAX_VALUE);

long saturatedAdd(long x, long y) {
    BigInteger sum = BigInteger.valueOf(x).add(BigInteger.valueOf(y));
    return bigMin.max(sum).min(bigMax).longValue();
}

however performance is important so this method is not ideal (though useful for testing.)

I don't know whether avoiding branching can significantly affect performance in Java. I assume it can, but I would like to benchmark methods both with and without branching.

Related: http://stackoverflow.com/questions/121240/saturating-addition-in-c

© Stack Overflow or respective owner

Related posts about java

Related posts about arithmetic