猿问

Java 手动溢出处理不需要的输出

我有以下程序平方和 1^2 + 2^2 + … + N^2 计算为: 示例输出:


java SumSquares 2 = 5


java SumSquares 3 = 14


java SumSquares 1000000 = 333333833333500000


这是我到目前为止所拥有的:


        int N = Integer.parseInt(args[0]);

        int sum = 0;

        long R;


        for (int i = 1; i <= N; i++) {

            R = i * i;

            if (i != R / i) {

                System.err.println("Overflow at i = " + i);

                System.exit(1);

            }

            sum += R;

        }

        System.out.println(sum);

我的输出是 java SumSquares 100000000 Overflow at i = 46341


由于 46341^2 通过了 MAX INT。


我只是无法让程序输出以下说明,任何关于如何获取的想法


java SumSquares 100000000 在 i = 3024616 处溢出


我可以将整数更改为长整数,但这会否定溢出检查的需要。


从规格:


计算会溢出。我需要通过检查新总和是否(严格)小于旧总和来准确确定总和中发生溢出的点。


java SumSquares 100000000 在 i = 3024616 处溢出


请注意,以上必须通过循环中的一般溢出处理来实现,而不是通过某些预先确定的输入测试来实现。因此,当用于求和的整数类型被更大的类型替换时,您的程序将完全使用新的扩展范围。


只是为了澄清:是否有可能获得输出


java SumSquares 100000000 在 i = 3024616 处溢出


根据规范。


catspeake
浏览 154回答 2
2回答

鸿蒙传说

无需使用 long,您可以在实际执行操作之前检查两个整数的乘法是否会溢出:int a = 500000; //or -500000int b = 900000; //or -900000System.out.println(isOverflowOrUnderflow(a, b));//Returns true if multiplication of a, b results in an overflow or underflow..public static boolean isOverflowOrUnderflow(int a, int b) {&nbsp; &nbsp; return ((a > Integer.MAX_VALUE / b) || (a < Integer.MIN_VALUE / b) || ((a == -1) && (b == Integer.MIN_VALUE)) || ((b == -1) && (a == Integer.MIN_VALUE)));}使用您的代码的示例:public class Main {&nbsp; &nbsp; public static void main (String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; int N = Integer.parseInt(args[0]); //Where args[0] = "1000000"..&nbsp; &nbsp; &nbsp; &nbsp; int sum = 0;&nbsp; &nbsp; &nbsp; &nbsp; long R;&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 1; i <= N; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (Main.isOverflowOrUnderflow(i, i)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.err.println("Overflow at i = " + i);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.exit(1);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; R = i * i;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sum += R;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(sum);&nbsp; &nbsp; }&nbsp; &nbsp; public static boolean isOverflowOrUnderflow(int a, int b) {&nbsp; &nbsp; &nbsp; &nbsp; return ((a > Integer.MAX_VALUE / b) || (a < Integer.MIN_VALUE / b) || ((a == -1) && (b == Integer.MIN_VALUE)) || ((b == -1) && (a == Integer.MIN_VALUE)));&nbsp; &nbsp; }}输出:Overflow at i = 46341Command exited with non-zero status 1

湖上湖

您有 2 个错误:R = i * i仍然使用数学执行乘法,并且在乘法已经溢出到负值之前int不会将值扩大到。long您需要将其中至少一个转换long为R = i * (long) i.if (i != R / i)不是溢出的正确测试。只需检查该long值是否超出范围int:if (r > Integer.MAX_VALUE)static int sumOfSquares(int n) {&nbsp; &nbsp; int sum = 0;&nbsp; &nbsp; for (int i = 1; i <= n; i++) {&nbsp; &nbsp; &nbsp; &nbsp; long r = i * (long) i;&nbsp; &nbsp; &nbsp; &nbsp; if (r > Integer.MAX_VALUE) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.err.println("Overflow at i = " + i);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.exit(1);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; sum += r;&nbsp; &nbsp; }&nbsp; &nbsp; return sum;}测试System.out.println(sumOfSquares(2));System.out.println(sumOfSquares(3));System.out.println(sumOfSquares(1000000));输出514Overflow at i = 46341另一种防止溢出的方法是使用Math.multiplyExact()andMath.addExact()方法。static int sumOfSquares(int n) {&nbsp; &nbsp; int sum = 0;&nbsp; &nbsp; for (int i = 1; i <= n; i++) {&nbsp; &nbsp; &nbsp; &nbsp; int r = Math.multiplyExact(i, i);&nbsp; &nbsp; &nbsp; &nbsp; sum = Math.addExact(sum, r);&nbsp; &nbsp; }&nbsp; &nbsp; return sum;}输出514Exception in thread "main" java.lang.ArithmeticException: integer overflow&nbsp; &nbsp; at java.base/java.lang.Math.addExact(Math.java:825)&nbsp; &nbsp; at Test.sumOfSquares(Test.java:12)&nbsp; &nbsp; at Test.main(Test.java:6)如果您想要更好的错误消息,或者捕获异常:static int sumOfSquares(int n) {&nbsp; &nbsp; int sum = 0;&nbsp; &nbsp; for (int i = 1; i <= n; i++) {&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int r = Math.multiplyExact(i, i);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sum = Math.addExact(sum, r);&nbsp; &nbsp; &nbsp; &nbsp; } catch (@SuppressWarnings("unused") ArithmeticException ignored) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.err.println("Overflow at i = " + i);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.exit(1);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return sum;}输出514Overflow at i = 1861
随时随地看视频慕课网APP

相关分类

Java
我要回答