快速方法
这可能是一个解决方案(注意:始终使用有意义的变量名!):
private static int sum(int i, int... others) {
int sum = i;
if(others!=null)
for(int other : others) {
sum+=other;
}
}
System.out.println("sum:" + sum);
return sum;
}
注意论点。由于对 1 个数字求和不是很有意义,因此此构造确保至少有 1 个 int 进入。并且此构造还检查 vararg 中的空值。
满满的情绪...
执行此操作时,快速方法会发生什么:
int veryBigNumber = sum(Integer.MAX_VALUE, 1);
veryBigNumber
实际上会==Integer.MIN_VALUE
...
这可能是个问题。由于发生溢出时 Java 不会抛出异常,因此您最终可能会得到不正确的结果。您可以检查溢出:
private static int aLittleBitSaferSum(int i, int... others) throws ArithmeticException {
int sum = i;
if(others!=null)
for(int other : others) {
if(Integer.MAX_VALUE-other<sum) {
throw new ArithmeticException("Sum would be too large to fit in int");
}
if(Integer.MIN_VALUE+other>sum) {
throw new ArithmeticException("Sum would be too small to fit in int");
}
sum+=other;
}
}
System.out.println("sum: " + sum);
return sum;
}
当然,这只是一个愚蠢的检查......结果可能非常适合int
,例如:
sum(Integer.MAX_VALUE, 1, -1);
这应该会导致Integer.MAX_VALUE
- 它会在没有检查的情况下发生。
扩展视野
不要害怕!上述问题也可以解决。例如,通过提供一种巧妙的算法对操作数进行排序,以使部分结果始终适合int
范围,但我认为这是一个需要解决的问题......并且会花费大量计算能力。
但是,通过扩展函数处理的值的范围,它可以做得更好:
private static int aLittleBitSaferSum(int i, int... others) throws ArithmeticException {
long sum = i;
if(others!=null)
for(int other : others) {
if(Long.MAX_VALUE-other<sum) {
throw new ArithmeticException("Sum would be too large for this algorithm to deal with");
}
if(Long.MIN_VALUE+other>sum) {
throw new ArithmeticException("Sum would be too small for this algorithm to deal with");
}
sum+=other;
}
}
if(Integer.MAX_VALUE<sum) {
throw new ArithmeticException("Sum would be too large to fit in int");
}
if(Integer.MIN_VALUE>sum) {
throw new ArithmeticException("Sum would be too small to fit in int");
}
System.out.println("sum: " + sum);
return (int)sum;
}
这仍然有局限性,同样long
如此,但由于long
是整数大小的两倍,它引起问题的可能性要小得多。然而,由于涉及额外的工作,这有点慢,而且由于检查,可读性也降低了很多。
我全都要
……我现在就想要。范围仍然可能是一个问题,这是一个解决方案:
private static int aSafeButSlowerSum(int i, int... others) throws ArithmeticException {
BigInteger sum = BigInteger.valueOf(i);
BigInteger intMax = BigInteger.valueOf(Integer.MAX_VALUE); //should be a private static final class variable
BigInteger intMin = BigInteger.valueOf(Integer.MIN_VALUE); //should be a private static final class variable
if(others!=null)
for(int other : others) {
sum=sum.add(BigInteger.valueOf(i));
}
}
if(intMax.compareTo(sum)<0) {
throw new ArithmeticException("Sum would be too large to fit in int");
}
if(intMin.compareTo(sum)>0) {
throw new ArithmeticException("Sum would be too small to fit in int");
}
System.out.println("sum: " + sum.toString());
return sum.intValue;
}
由于所有 BigInteger 的东西,这甚至更慢,但显示上述功能没有问题。(因此与其他选项一样,“现在”会少一些,但要为额外的东西付出代价..)