如何long
在 Java 中添加两个值,以便如果结果溢出则将其限制在范围内Long.MIN_VALUE
.. Long.MAX_VALUE
?
对于添加整数,可以精确地执行算术long
并将结果转换回int
,例如:
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;
}
或者
import com.google.common.primitives.Ints;
int saturatedAdd(int x, int y) {
long sum = (long) x + (long) y;
return Ints.saturatedCast(sum);
}
但在long
没有更大的原始类型可以容纳中间(非钳位)总和的情况下。
由于这是 Java,我不能使用内联汇编(特别是 SSE 的饱和添加指令。)
它可以使用来实现BigInteger
,例如
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();
}
但是性能很重要,因此这种方法并不理想(尽管对测试很有用。)
我不知道避免分支是否会显着影响 Java 的性能。我认为它可以,但我想对有和没有分支的方法进行基准测试。