为什么Java不告诉我什么时候可以';不使用整数?

为什么Java不告诉我什么时候可以';不使用整数?,java,math,Java,Math,对于一个小项目(问题10 Euler项目),我试图将所有素数的总和都小于200万。因此,我使用了蛮力方法,从0迭代到2'000'000,并检查数字是否为素数。如果是,我将其添加到总额中: private int sum = 0; private void calculate() { for (int i = 0; i < 2000000; i++) { if (i.isPrime()) { sum = sum + i; } }

对于一个小项目(问题10 Euler项目),我试图将所有素数的总和都小于200万。因此,我使用了蛮力方法,从0迭代到2'000'000,并检查数字是否为素数。如果是,我将其添加到总额中:

private int sum = 0;

private void calculate() {
   for (int i = 0; i < 2000000; i++) {
      if (i.isPrime()) {
         sum = sum + i;
      }
   }
   sysout(sum)
}
private int sum=0;
私有无效计算(){
对于(int i=0;i<2000000;i++){
if(i.isPrime()){
sum=sum+i;
}
}
系统输出(总和)
}

此计算结果为1179908154,但这是不正确的。所以我把int改为biginger,现在我得到了正确的和142913828922。显然int的范围溢出了。但是为什么Java不能告诉我呢?(例如,通过异常)

因为您可能希望它以传统的整数方式运行。例外情况只适用于绝对错误且无法挽回的事情

ETA:来自语言规范:

“内置的整数运算符不支持 在任何情况下指示溢流或下溢 唯一的数字运算符 可以引发异常(§11)是 整数除法运算符/(§15.17.2) 和整数余数运算符% (§15.17.3),其中 如果右边的 操作数为零。”


()

除了Jim所说的,检查溢出等情况会给任何整数计算增加性能损失,这将使执行大量计算的程序速度大大降低。

了解Integer.MAX\u值总是很有用:)

另一个原因是,您可以轻松快速地执行此检查

if (sum+i < sum) {
  throw new AritchmeticException();
}
if(sum+i

如果你知道我总是正的,并且小于整数。MAX_值,那么这个技巧应该做得很好。

因为我们的职业看重性能而不是正确性;(


默认情况下使用BigInteger,如果性能是一个真正的问题,则仅推理使用long或int是否可以接受,这将有助于避免此类问题。

那么,如果超出范围,我应该在添加数字之前进行测试?如果您知道数字可能很大,则应该使用“更大”类来处理它。我同意Felipe的观点。如果你需要保证x+1>x用于大于整数范围的值,请使用BigInteger。如果你出于其他原因使用整数,整数应该可以。@Jim Kiley-或
Long
/
Long
,用于大于整数范围但肯定始终在Long范围内的数字(
Long.MAX\u Long
~=2^63),将是一个更自然的替代品。这并不是说,
biginger
s没有用处,但它们更专业一些。
因为可以想象,您可能希望它以传统的整数方式运行。
可以想象,您只需要在传统的整数方式中运行任何方便的功能方法(例如,超出数组边界)我们不这样做的原因是,将普通情况作为默认情况比绝对权力重要得多。顺便说一句,BigInteger是一种滥杀滥伤,而且long也可以很好地工作。你为什么不使用埃拉托斯筛而不是暴力强迫它?@DJClayworth:我试试@CoolBeans:暴力强迫足够快,只需要一小部分时间作为一般规则,迭代数值计算必须分析溢出、下溢、精度损失等。这在数学中是一个非常重要的问题,所以编译器不会很快为您解决。谢谢。学到了一些新东西!这就是为什么这样做的真正原因。这也是为什么我们有原语!@Vuntic I d我不认为这是我们使用原语的真正原因——在其他语言中(例如Scala)例如,当您使用Int类时,编译器足够聪明,可以使用本机整数。换句话说,如果Java编译器变得更聪明,则不需要在编程语言中公开原始数据类型。1)您正在比较两种起源相隔15年以上的语言。2) Java编译器不允许“智能”并用另一种类型替换一种类型。。。除非JLS对此进行制裁。(确定赋值的规则是另一个例子,Java编译器不允许“智能化”。)实际上是因为Java语言设计者想让程序员选择重视性能而不是正确性。