是否可以编写程序来阻止 Java 将整数提升为长整数

Is it possible to make program which will stop Java from promoting integer into long

Scanner num=new Scanner(System.in);
  System.out.println("Enter  number in range from 1 to 20");
  int n=num.nextInt();
    int product=1;
    for(int i=1;i<=n;i++){
        product*=i;
        if(product>Integer.MAX_VALUE || product<Integer.MIN_VALUE){
         System.err.println("Out od Integer boundary");
        }
        else System.out.println("Product of numbers between 1 and "+n+" is "+product);
        }

        }
      }    

我正在处理相同的基本任务,这个特别的任务是: 计算 1 到 11、1 到 12、1 到 13 和 1 到 14 的乘积。写下所得的乘积并判断结果是否正确。 接着 提示:1到13(=6227020800)的乘积在int [-2147483648, 2147483647]范围外,但在long范围内。请注意,即使一切看起来都是正确的,计算机程序也可能不会给出正确的答案! 所以如果我理解正确 Java 会自动将 int 值转换为 long 值,但我正在考虑制作不允许这样做的程序。有可能吗?也可以随意解释代码或我的 thinking.Thanks 中的任何不正确之处。 p.s抱歉英语不好。

Java 会自动将 int 转换为 long,但仅限于特定情况。具体来说,如果某些东西被声明为 long,而你给它一个 int,程序是合法的,int 将被转换为 long(数值将相同)。示例:

int a = 100;
long b = a;  // legal
int c;
b = c;  // legal

public static void doSomethingWithLong(long x) { ... }

int d = 100;
doSomethingWithLong(d);  // legal

Java 将 int 提升为 long 的另一种情况是,如果您有一个涉及 longint 的算术表达式:

long a = 10000000000L;
int b = 3;
long c = a + b;

此处 b 被提升为表达式内部的 long 以便它可以向其添加 a + b。但是由于数值相同,所以它被提升的事实可能只与实现者相关。

但这就是所有 Java 所做的。如果您将一个变量或参数声明为 int,则该变量不会因为您尝试将太大的值放入其中而重新声明为 long。它仍然是 int。如果您尝试计算一个太大的值,它将回绕,您将得到错误的答案。

(P.S。此自动转换仅在转换为 "wider" 类型时有效。两种方式均无效:

long a = 10;
int b = a;  // error

这是一个错误,即使 a 的值实际上适合 int。 Java 不会在没有转换的情况下自动将 long 转换为 int。)

如果我对问题的理解正确,简单的解决方案是使用 Math.multiplyExact(出现在 Java 8):

import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        Scanner num = new Scanner(System.in);
        System.out.println("Enter  number in range from 1 to 20");
        int n = num.nextInt();
        int product = 1;
        try {
            for (int i = 1; i <= n; i++) {
                product = Math.multiplyExact(product, i);
            }
            System.out.println("Product of numbers between 1 and " + n + " is " + product);
        } catch (ArithmeticException e) {
            System.err.println("Out of Integer boundary");
        }
    }
}

multiplyExact方法确保你的乘法结果不会溢出。如果是,则抛出一个 AriphmeticException 可以被捕获和处理。