Java manual overflow handling undesired output












1















I have the following program
The sum of squares 1^2 + 2^2 + … + N^2 is calculated as:
Example output:




java SumSquares 2 = 5



java SumSquares 3 = 14



java SumSquares 1000000 = 333333833333500000




Here's what I have so far:



        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);



My output is java SumSquares 100000000
Overflow at i = 46341




As 46341^2 passes MAX INT.



I just can't get the program to out put the below instructions, any ideas on how to get




java SumSquares 100000000
Overflow at i = 3024616




I could change the ints to longs but that would negate the need for the overflow checking.



From specification:



The computation will overflow. I need to exactly determine the point in the summation where the overflow happens, via checking whether the new sum is (strictly) less than the old sum.




java SumSquares 100000000
Overflow at i = 3024616




Note that the above must be achieved by a general overflow-handling in the loop, not by some pre-determined input-testing. So that when the integer-type used for the summation is replaced by some bigger type, your program will fully use the new extended range.



Just to clarify:
Is it possible to get the output




java SumSquares 100000000
Overflow at i = 3024616




As per the specification.










share|improve this question

























  • if(i + n >= Integer.MAX_VALUE)?

    – MeetTitan
    Nov 14 '18 at 0:55











  • I guess one way to do this is to divide R by i. If the result is not i, then it likely overflowed.

    – markspace
    Nov 14 '18 at 0:59











  • The problem is that once overflow occurs, then the resulting bit pattern is unpredicatble, and it's hard to say what test in general could be preformed on R alone to check for an overflow.

    – markspace
    Nov 14 '18 at 1:00











  • Also for this specific case, you could just find the square root of Integer.MAX_INT. If i is ever greater than that value, it'll overflow, no need to check further. Something like public static final int SQ_MAX = (int)Math.sqrt( (double)Integer.MAX_VALUE);

    – markspace
    Nov 14 '18 at 1:04













  • @markspace: in C (and C++) signed integer overflow is undefined behavior (and possibly not even a value with any bit pattern), but in Java it is reliably truncation of 2s-complement at 32bits or 64bits.

    – dave_thompson_085
    Nov 14 '18 at 2:51
















1















I have the following program
The sum of squares 1^2 + 2^2 + … + N^2 is calculated as:
Example output:




java SumSquares 2 = 5



java SumSquares 3 = 14



java SumSquares 1000000 = 333333833333500000




Here's what I have so far:



        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);



My output is java SumSquares 100000000
Overflow at i = 46341




As 46341^2 passes MAX INT.



I just can't get the program to out put the below instructions, any ideas on how to get




java SumSquares 100000000
Overflow at i = 3024616




I could change the ints to longs but that would negate the need for the overflow checking.



From specification:



The computation will overflow. I need to exactly determine the point in the summation where the overflow happens, via checking whether the new sum is (strictly) less than the old sum.




java SumSquares 100000000
Overflow at i = 3024616




Note that the above must be achieved by a general overflow-handling in the loop, not by some pre-determined input-testing. So that when the integer-type used for the summation is replaced by some bigger type, your program will fully use the new extended range.



Just to clarify:
Is it possible to get the output




java SumSquares 100000000
Overflow at i = 3024616




As per the specification.










share|improve this question

























  • if(i + n >= Integer.MAX_VALUE)?

    – MeetTitan
    Nov 14 '18 at 0:55











  • I guess one way to do this is to divide R by i. If the result is not i, then it likely overflowed.

    – markspace
    Nov 14 '18 at 0:59











  • The problem is that once overflow occurs, then the resulting bit pattern is unpredicatble, and it's hard to say what test in general could be preformed on R alone to check for an overflow.

    – markspace
    Nov 14 '18 at 1:00











  • Also for this specific case, you could just find the square root of Integer.MAX_INT. If i is ever greater than that value, it'll overflow, no need to check further. Something like public static final int SQ_MAX = (int)Math.sqrt( (double)Integer.MAX_VALUE);

    – markspace
    Nov 14 '18 at 1:04













  • @markspace: in C (and C++) signed integer overflow is undefined behavior (and possibly not even a value with any bit pattern), but in Java it is reliably truncation of 2s-complement at 32bits or 64bits.

    – dave_thompson_085
    Nov 14 '18 at 2:51














1












1








1








I have the following program
The sum of squares 1^2 + 2^2 + … + N^2 is calculated as:
Example output:




java SumSquares 2 = 5



java SumSquares 3 = 14



java SumSquares 1000000 = 333333833333500000




Here's what I have so far:



        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);



My output is java SumSquares 100000000
Overflow at i = 46341




As 46341^2 passes MAX INT.



I just can't get the program to out put the below instructions, any ideas on how to get




java SumSquares 100000000
Overflow at i = 3024616




I could change the ints to longs but that would negate the need for the overflow checking.



From specification:



The computation will overflow. I need to exactly determine the point in the summation where the overflow happens, via checking whether the new sum is (strictly) less than the old sum.




java SumSquares 100000000
Overflow at i = 3024616




Note that the above must be achieved by a general overflow-handling in the loop, not by some pre-determined input-testing. So that when the integer-type used for the summation is replaced by some bigger type, your program will fully use the new extended range.



Just to clarify:
Is it possible to get the output




java SumSquares 100000000
Overflow at i = 3024616




As per the specification.










share|improve this question
















I have the following program
The sum of squares 1^2 + 2^2 + … + N^2 is calculated as:
Example output:




java SumSquares 2 = 5



java SumSquares 3 = 14



java SumSquares 1000000 = 333333833333500000




Here's what I have so far:



        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);



My output is java SumSquares 100000000
Overflow at i = 46341




As 46341^2 passes MAX INT.



I just can't get the program to out put the below instructions, any ideas on how to get




java SumSquares 100000000
Overflow at i = 3024616




I could change the ints to longs but that would negate the need for the overflow checking.



From specification:



The computation will overflow. I need to exactly determine the point in the summation where the overflow happens, via checking whether the new sum is (strictly) less than the old sum.




java SumSquares 100000000
Overflow at i = 3024616




Note that the above must be achieved by a general overflow-handling in the loop, not by some pre-determined input-testing. So that when the integer-type used for the summation is replaced by some bigger type, your program will fully use the new extended range.



Just to clarify:
Is it possible to get the output




java SumSquares 100000000
Overflow at i = 3024616




As per the specification.







java






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 14 '18 at 2:06







Javasaurusrex

















asked Nov 14 '18 at 0:49









JavasaurusrexJavasaurusrex

164




164













  • if(i + n >= Integer.MAX_VALUE)?

    – MeetTitan
    Nov 14 '18 at 0:55











  • I guess one way to do this is to divide R by i. If the result is not i, then it likely overflowed.

    – markspace
    Nov 14 '18 at 0:59











  • The problem is that once overflow occurs, then the resulting bit pattern is unpredicatble, and it's hard to say what test in general could be preformed on R alone to check for an overflow.

    – markspace
    Nov 14 '18 at 1:00











  • Also for this specific case, you could just find the square root of Integer.MAX_INT. If i is ever greater than that value, it'll overflow, no need to check further. Something like public static final int SQ_MAX = (int)Math.sqrt( (double)Integer.MAX_VALUE);

    – markspace
    Nov 14 '18 at 1:04













  • @markspace: in C (and C++) signed integer overflow is undefined behavior (and possibly not even a value with any bit pattern), but in Java it is reliably truncation of 2s-complement at 32bits or 64bits.

    – dave_thompson_085
    Nov 14 '18 at 2:51



















  • if(i + n >= Integer.MAX_VALUE)?

    – MeetTitan
    Nov 14 '18 at 0:55











  • I guess one way to do this is to divide R by i. If the result is not i, then it likely overflowed.

    – markspace
    Nov 14 '18 at 0:59











  • The problem is that once overflow occurs, then the resulting bit pattern is unpredicatble, and it's hard to say what test in general could be preformed on R alone to check for an overflow.

    – markspace
    Nov 14 '18 at 1:00











  • Also for this specific case, you could just find the square root of Integer.MAX_INT. If i is ever greater than that value, it'll overflow, no need to check further. Something like public static final int SQ_MAX = (int)Math.sqrt( (double)Integer.MAX_VALUE);

    – markspace
    Nov 14 '18 at 1:04













  • @markspace: in C (and C++) signed integer overflow is undefined behavior (and possibly not even a value with any bit pattern), but in Java it is reliably truncation of 2s-complement at 32bits or 64bits.

    – dave_thompson_085
    Nov 14 '18 at 2:51

















if(i + n >= Integer.MAX_VALUE)?

– MeetTitan
Nov 14 '18 at 0:55





if(i + n >= Integer.MAX_VALUE)?

– MeetTitan
Nov 14 '18 at 0:55













I guess one way to do this is to divide R by i. If the result is not i, then it likely overflowed.

– markspace
Nov 14 '18 at 0:59





I guess one way to do this is to divide R by i. If the result is not i, then it likely overflowed.

– markspace
Nov 14 '18 at 0:59













The problem is that once overflow occurs, then the resulting bit pattern is unpredicatble, and it's hard to say what test in general could be preformed on R alone to check for an overflow.

– markspace
Nov 14 '18 at 1:00





The problem is that once overflow occurs, then the resulting bit pattern is unpredicatble, and it's hard to say what test in general could be preformed on R alone to check for an overflow.

– markspace
Nov 14 '18 at 1:00













Also for this specific case, you could just find the square root of Integer.MAX_INT. If i is ever greater than that value, it'll overflow, no need to check further. Something like public static final int SQ_MAX = (int)Math.sqrt( (double)Integer.MAX_VALUE);

– markspace
Nov 14 '18 at 1:04







Also for this specific case, you could just find the square root of Integer.MAX_INT. If i is ever greater than that value, it'll overflow, no need to check further. Something like public static final int SQ_MAX = (int)Math.sqrt( (double)Integer.MAX_VALUE);

– markspace
Nov 14 '18 at 1:04















@markspace: in C (and C++) signed integer overflow is undefined behavior (and possibly not even a value with any bit pattern), but in Java it is reliably truncation of 2s-complement at 32bits or 64bits.

– dave_thompson_085
Nov 14 '18 at 2:51





@markspace: in C (and C++) signed integer overflow is undefined behavior (and possibly not even a value with any bit pattern), but in Java it is reliably truncation of 2s-complement at 32bits or 64bits.

– dave_thompson_085
Nov 14 '18 at 2:51












2 Answers
2






active

oldest

votes


















0














You have 2 errors:





  • R = i * i still performs the multiplication using int math, and doesn't widen the value to long until after multiplication has already overflowed to a negative value.



    You need to cast at least one of them to long, e.g. R = i * (long) i.



  • if (i != R / i) is not the right test for overflow. Simply check if the long value exceeds the range of int: if (r > Integer.MAX_VALUE)



static int sumOfSquares(int n) {
int sum = 0;
for (int i = 1; i <= n; i++) {
long r = i * (long) i;
if (r > Integer.MAX_VALUE) {
System.err.println("Overflow at i = " + i);
System.exit(1);
}
sum += r;
}
return sum;
}


Test



System.out.println(sumOfSquares(2));
System.out.println(sumOfSquares(3));
System.out.println(sumOfSquares(1000000));


Output



5
14
Overflow at i = 46341




Another way to guard against overflow is to use the Math.multiplyExact() and Math.addExact() methods.



static int sumOfSquares(int n) {
int sum = 0;
for (int i = 1; i <= n; i++) {
int r = Math.multiplyExact(i, i);
sum = Math.addExact(sum, r);
}
return sum;
}


Output



5
14
Exception in thread "main" java.lang.ArithmeticException: integer overflow
at java.base/java.lang.Math.addExact(Math.java:825)
at Test.sumOfSquares(Test.java:12)
at Test.main(Test.java:6)




Or catch the exception if you want a better error message:



static int sumOfSquares(int n) {
int sum = 0;
for (int i = 1; i <= n; i++) {
try {
int r = Math.multiplyExact(i, i);
sum = Math.addExact(sum, r);
} catch (@SuppressWarnings("unused") ArithmeticException ignored) {
System.err.println("Overflow at i = " + i);
System.exit(1);
}
}
return sum;
}


Output



5
14
Overflow at i = 1861





share|improve this answer


























  • multiplyExcat is a good idea, it's relatively new and I'd forgotten about it. I think the OP specifically ruled out using longs though for some reason.

    – markspace
    Nov 14 '18 at 1:01











  • @markspace OP didn't rule out using longs, since OP is using long R.

    – Andreas
    Nov 14 '18 at 1:05











  • I could change the ints to longs but that would negate the need for the overflow checking. OK now I'm not sure what is going on.

    – markspace
    Nov 14 '18 at 1:06











  • @markspace The "ints" are the sum and i variables. Of course, you could be right, since the point of the i != R / i check would be that R is also an int and it overflowed.

    – Andreas
    Nov 14 '18 at 1:07













  • Thank you for the responses. Essentially I need to have the output to match java SumSquares 100000000 Overflow at i = 3024616 Also to clarify- Math functions cannot be used nor try/catch. Only basic java. Yet I can't see any possible way

    – Javasaurusrex
    Nov 14 '18 at 1:09





















0














Without having to use longs, you can check if the multiplication of two integers will overflow before actually doing the operation:



int a = 500000; //or -500000
int b = 900000; //or -900000

System.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) {
return ((a > Integer.MAX_VALUE / b) || (a < Integer.MIN_VALUE / b) || ((a == -1) && (b == Integer.MIN_VALUE)) || ((b == -1) && (a == Integer.MIN_VALUE)));
}


Example using your code:



public class Main {
public static void main (String args) {
int N = Integer.parseInt(args[0]); //Where args[0] = "1000000"..
int sum = 0;
long R;

for (int i = 1; i <= N; i++) {
if (Main.isOverflowOrUnderflow(i, i)) {
System.err.println("Overflow at i = " + i);
System.exit(1);
}

R = i * i;
sum += R;
}

System.out.println(sum);
}

public static boolean isOverflowOrUnderflow(int a, int b) {
return ((a > Integer.MAX_VALUE / b) || (a < Integer.MIN_VALUE / b) || ((a == -1) && (b == Integer.MIN_VALUE)) || ((b == -1) && (a == Integer.MIN_VALUE)));
}
}


Outputs:



Overflow at i = 46341
Command exited with non-zero status 1





share|improve this answer

























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53291614%2fjava-manual-overflow-handling-undesired-output%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    You have 2 errors:





    • R = i * i still performs the multiplication using int math, and doesn't widen the value to long until after multiplication has already overflowed to a negative value.



      You need to cast at least one of them to long, e.g. R = i * (long) i.



    • if (i != R / i) is not the right test for overflow. Simply check if the long value exceeds the range of int: if (r > Integer.MAX_VALUE)



    static int sumOfSquares(int n) {
    int sum = 0;
    for (int i = 1; i <= n; i++) {
    long r = i * (long) i;
    if (r > Integer.MAX_VALUE) {
    System.err.println("Overflow at i = " + i);
    System.exit(1);
    }
    sum += r;
    }
    return sum;
    }


    Test



    System.out.println(sumOfSquares(2));
    System.out.println(sumOfSquares(3));
    System.out.println(sumOfSquares(1000000));


    Output



    5
    14
    Overflow at i = 46341




    Another way to guard against overflow is to use the Math.multiplyExact() and Math.addExact() methods.



    static int sumOfSquares(int n) {
    int sum = 0;
    for (int i = 1; i <= n; i++) {
    int r = Math.multiplyExact(i, i);
    sum = Math.addExact(sum, r);
    }
    return sum;
    }


    Output



    5
    14
    Exception in thread "main" java.lang.ArithmeticException: integer overflow
    at java.base/java.lang.Math.addExact(Math.java:825)
    at Test.sumOfSquares(Test.java:12)
    at Test.main(Test.java:6)




    Or catch the exception if you want a better error message:



    static int sumOfSquares(int n) {
    int sum = 0;
    for (int i = 1; i <= n; i++) {
    try {
    int r = Math.multiplyExact(i, i);
    sum = Math.addExact(sum, r);
    } catch (@SuppressWarnings("unused") ArithmeticException ignored) {
    System.err.println("Overflow at i = " + i);
    System.exit(1);
    }
    }
    return sum;
    }


    Output



    5
    14
    Overflow at i = 1861





    share|improve this answer


























    • multiplyExcat is a good idea, it's relatively new and I'd forgotten about it. I think the OP specifically ruled out using longs though for some reason.

      – markspace
      Nov 14 '18 at 1:01











    • @markspace OP didn't rule out using longs, since OP is using long R.

      – Andreas
      Nov 14 '18 at 1:05











    • I could change the ints to longs but that would negate the need for the overflow checking. OK now I'm not sure what is going on.

      – markspace
      Nov 14 '18 at 1:06











    • @markspace The "ints" are the sum and i variables. Of course, you could be right, since the point of the i != R / i check would be that R is also an int and it overflowed.

      – Andreas
      Nov 14 '18 at 1:07













    • Thank you for the responses. Essentially I need to have the output to match java SumSquares 100000000 Overflow at i = 3024616 Also to clarify- Math functions cannot be used nor try/catch. Only basic java. Yet I can't see any possible way

      – Javasaurusrex
      Nov 14 '18 at 1:09


















    0














    You have 2 errors:





    • R = i * i still performs the multiplication using int math, and doesn't widen the value to long until after multiplication has already overflowed to a negative value.



      You need to cast at least one of them to long, e.g. R = i * (long) i.



    • if (i != R / i) is not the right test for overflow. Simply check if the long value exceeds the range of int: if (r > Integer.MAX_VALUE)



    static int sumOfSquares(int n) {
    int sum = 0;
    for (int i = 1; i <= n; i++) {
    long r = i * (long) i;
    if (r > Integer.MAX_VALUE) {
    System.err.println("Overflow at i = " + i);
    System.exit(1);
    }
    sum += r;
    }
    return sum;
    }


    Test



    System.out.println(sumOfSquares(2));
    System.out.println(sumOfSquares(3));
    System.out.println(sumOfSquares(1000000));


    Output



    5
    14
    Overflow at i = 46341




    Another way to guard against overflow is to use the Math.multiplyExact() and Math.addExact() methods.



    static int sumOfSquares(int n) {
    int sum = 0;
    for (int i = 1; i <= n; i++) {
    int r = Math.multiplyExact(i, i);
    sum = Math.addExact(sum, r);
    }
    return sum;
    }


    Output



    5
    14
    Exception in thread "main" java.lang.ArithmeticException: integer overflow
    at java.base/java.lang.Math.addExact(Math.java:825)
    at Test.sumOfSquares(Test.java:12)
    at Test.main(Test.java:6)




    Or catch the exception if you want a better error message:



    static int sumOfSquares(int n) {
    int sum = 0;
    for (int i = 1; i <= n; i++) {
    try {
    int r = Math.multiplyExact(i, i);
    sum = Math.addExact(sum, r);
    } catch (@SuppressWarnings("unused") ArithmeticException ignored) {
    System.err.println("Overflow at i = " + i);
    System.exit(1);
    }
    }
    return sum;
    }


    Output



    5
    14
    Overflow at i = 1861





    share|improve this answer


























    • multiplyExcat is a good idea, it's relatively new and I'd forgotten about it. I think the OP specifically ruled out using longs though for some reason.

      – markspace
      Nov 14 '18 at 1:01











    • @markspace OP didn't rule out using longs, since OP is using long R.

      – Andreas
      Nov 14 '18 at 1:05











    • I could change the ints to longs but that would negate the need for the overflow checking. OK now I'm not sure what is going on.

      – markspace
      Nov 14 '18 at 1:06











    • @markspace The "ints" are the sum and i variables. Of course, you could be right, since the point of the i != R / i check would be that R is also an int and it overflowed.

      – Andreas
      Nov 14 '18 at 1:07













    • Thank you for the responses. Essentially I need to have the output to match java SumSquares 100000000 Overflow at i = 3024616 Also to clarify- Math functions cannot be used nor try/catch. Only basic java. Yet I can't see any possible way

      – Javasaurusrex
      Nov 14 '18 at 1:09
















    0












    0








    0







    You have 2 errors:





    • R = i * i still performs the multiplication using int math, and doesn't widen the value to long until after multiplication has already overflowed to a negative value.



      You need to cast at least one of them to long, e.g. R = i * (long) i.



    • if (i != R / i) is not the right test for overflow. Simply check if the long value exceeds the range of int: if (r > Integer.MAX_VALUE)



    static int sumOfSquares(int n) {
    int sum = 0;
    for (int i = 1; i <= n; i++) {
    long r = i * (long) i;
    if (r > Integer.MAX_VALUE) {
    System.err.println("Overflow at i = " + i);
    System.exit(1);
    }
    sum += r;
    }
    return sum;
    }


    Test



    System.out.println(sumOfSquares(2));
    System.out.println(sumOfSquares(3));
    System.out.println(sumOfSquares(1000000));


    Output



    5
    14
    Overflow at i = 46341




    Another way to guard against overflow is to use the Math.multiplyExact() and Math.addExact() methods.



    static int sumOfSquares(int n) {
    int sum = 0;
    for (int i = 1; i <= n; i++) {
    int r = Math.multiplyExact(i, i);
    sum = Math.addExact(sum, r);
    }
    return sum;
    }


    Output



    5
    14
    Exception in thread "main" java.lang.ArithmeticException: integer overflow
    at java.base/java.lang.Math.addExact(Math.java:825)
    at Test.sumOfSquares(Test.java:12)
    at Test.main(Test.java:6)




    Or catch the exception if you want a better error message:



    static int sumOfSquares(int n) {
    int sum = 0;
    for (int i = 1; i <= n; i++) {
    try {
    int r = Math.multiplyExact(i, i);
    sum = Math.addExact(sum, r);
    } catch (@SuppressWarnings("unused") ArithmeticException ignored) {
    System.err.println("Overflow at i = " + i);
    System.exit(1);
    }
    }
    return sum;
    }


    Output



    5
    14
    Overflow at i = 1861





    share|improve this answer















    You have 2 errors:





    • R = i * i still performs the multiplication using int math, and doesn't widen the value to long until after multiplication has already overflowed to a negative value.



      You need to cast at least one of them to long, e.g. R = i * (long) i.



    • if (i != R / i) is not the right test for overflow. Simply check if the long value exceeds the range of int: if (r > Integer.MAX_VALUE)



    static int sumOfSquares(int n) {
    int sum = 0;
    for (int i = 1; i <= n; i++) {
    long r = i * (long) i;
    if (r > Integer.MAX_VALUE) {
    System.err.println("Overflow at i = " + i);
    System.exit(1);
    }
    sum += r;
    }
    return sum;
    }


    Test



    System.out.println(sumOfSquares(2));
    System.out.println(sumOfSquares(3));
    System.out.println(sumOfSquares(1000000));


    Output



    5
    14
    Overflow at i = 46341




    Another way to guard against overflow is to use the Math.multiplyExact() and Math.addExact() methods.



    static int sumOfSquares(int n) {
    int sum = 0;
    for (int i = 1; i <= n; i++) {
    int r = Math.multiplyExact(i, i);
    sum = Math.addExact(sum, r);
    }
    return sum;
    }


    Output



    5
    14
    Exception in thread "main" java.lang.ArithmeticException: integer overflow
    at java.base/java.lang.Math.addExact(Math.java:825)
    at Test.sumOfSquares(Test.java:12)
    at Test.main(Test.java:6)




    Or catch the exception if you want a better error message:



    static int sumOfSquares(int n) {
    int sum = 0;
    for (int i = 1; i <= n; i++) {
    try {
    int r = Math.multiplyExact(i, i);
    sum = Math.addExact(sum, r);
    } catch (@SuppressWarnings("unused") ArithmeticException ignored) {
    System.err.println("Overflow at i = " + i);
    System.exit(1);
    }
    }
    return sum;
    }


    Output



    5
    14
    Overflow at i = 1861






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 14 '18 at 1:07

























    answered Nov 14 '18 at 1:00









    AndreasAndreas

    76.3k463123




    76.3k463123













    • multiplyExcat is a good idea, it's relatively new and I'd forgotten about it. I think the OP specifically ruled out using longs though for some reason.

      – markspace
      Nov 14 '18 at 1:01











    • @markspace OP didn't rule out using longs, since OP is using long R.

      – Andreas
      Nov 14 '18 at 1:05











    • I could change the ints to longs but that would negate the need for the overflow checking. OK now I'm not sure what is going on.

      – markspace
      Nov 14 '18 at 1:06











    • @markspace The "ints" are the sum and i variables. Of course, you could be right, since the point of the i != R / i check would be that R is also an int and it overflowed.

      – Andreas
      Nov 14 '18 at 1:07













    • Thank you for the responses. Essentially I need to have the output to match java SumSquares 100000000 Overflow at i = 3024616 Also to clarify- Math functions cannot be used nor try/catch. Only basic java. Yet I can't see any possible way

      – Javasaurusrex
      Nov 14 '18 at 1:09





















    • multiplyExcat is a good idea, it's relatively new and I'd forgotten about it. I think the OP specifically ruled out using longs though for some reason.

      – markspace
      Nov 14 '18 at 1:01











    • @markspace OP didn't rule out using longs, since OP is using long R.

      – Andreas
      Nov 14 '18 at 1:05











    • I could change the ints to longs but that would negate the need for the overflow checking. OK now I'm not sure what is going on.

      – markspace
      Nov 14 '18 at 1:06











    • @markspace The "ints" are the sum and i variables. Of course, you could be right, since the point of the i != R / i check would be that R is also an int and it overflowed.

      – Andreas
      Nov 14 '18 at 1:07













    • Thank you for the responses. Essentially I need to have the output to match java SumSquares 100000000 Overflow at i = 3024616 Also to clarify- Math functions cannot be used nor try/catch. Only basic java. Yet I can't see any possible way

      – Javasaurusrex
      Nov 14 '18 at 1:09



















    multiplyExcat is a good idea, it's relatively new and I'd forgotten about it. I think the OP specifically ruled out using longs though for some reason.

    – markspace
    Nov 14 '18 at 1:01





    multiplyExcat is a good idea, it's relatively new and I'd forgotten about it. I think the OP specifically ruled out using longs though for some reason.

    – markspace
    Nov 14 '18 at 1:01













    @markspace OP didn't rule out using longs, since OP is using long R.

    – Andreas
    Nov 14 '18 at 1:05





    @markspace OP didn't rule out using longs, since OP is using long R.

    – Andreas
    Nov 14 '18 at 1:05













    I could change the ints to longs but that would negate the need for the overflow checking. OK now I'm not sure what is going on.

    – markspace
    Nov 14 '18 at 1:06





    I could change the ints to longs but that would negate the need for the overflow checking. OK now I'm not sure what is going on.

    – markspace
    Nov 14 '18 at 1:06













    @markspace The "ints" are the sum and i variables. Of course, you could be right, since the point of the i != R / i check would be that R is also an int and it overflowed.

    – Andreas
    Nov 14 '18 at 1:07







    @markspace The "ints" are the sum and i variables. Of course, you could be right, since the point of the i != R / i check would be that R is also an int and it overflowed.

    – Andreas
    Nov 14 '18 at 1:07















    Thank you for the responses. Essentially I need to have the output to match java SumSquares 100000000 Overflow at i = 3024616 Also to clarify- Math functions cannot be used nor try/catch. Only basic java. Yet I can't see any possible way

    – Javasaurusrex
    Nov 14 '18 at 1:09







    Thank you for the responses. Essentially I need to have the output to match java SumSquares 100000000 Overflow at i = 3024616 Also to clarify- Math functions cannot be used nor try/catch. Only basic java. Yet I can't see any possible way

    – Javasaurusrex
    Nov 14 '18 at 1:09















    0














    Without having to use longs, you can check if the multiplication of two integers will overflow before actually doing the operation:



    int a = 500000; //or -500000
    int b = 900000; //or -900000

    System.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) {
    return ((a > Integer.MAX_VALUE / b) || (a < Integer.MIN_VALUE / b) || ((a == -1) && (b == Integer.MIN_VALUE)) || ((b == -1) && (a == Integer.MIN_VALUE)));
    }


    Example using your code:



    public class Main {
    public static void main (String args) {
    int N = Integer.parseInt(args[0]); //Where args[0] = "1000000"..
    int sum = 0;
    long R;

    for (int i = 1; i <= N; i++) {
    if (Main.isOverflowOrUnderflow(i, i)) {
    System.err.println("Overflow at i = " + i);
    System.exit(1);
    }

    R = i * i;
    sum += R;
    }

    System.out.println(sum);
    }

    public static boolean isOverflowOrUnderflow(int a, int b) {
    return ((a > Integer.MAX_VALUE / b) || (a < Integer.MIN_VALUE / b) || ((a == -1) && (b == Integer.MIN_VALUE)) || ((b == -1) && (a == Integer.MIN_VALUE)));
    }
    }


    Outputs:



    Overflow at i = 46341
    Command exited with non-zero status 1





    share|improve this answer






























      0














      Without having to use longs, you can check if the multiplication of two integers will overflow before actually doing the operation:



      int a = 500000; //or -500000
      int b = 900000; //or -900000

      System.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) {
      return ((a > Integer.MAX_VALUE / b) || (a < Integer.MIN_VALUE / b) || ((a == -1) && (b == Integer.MIN_VALUE)) || ((b == -1) && (a == Integer.MIN_VALUE)));
      }


      Example using your code:



      public class Main {
      public static void main (String args) {
      int N = Integer.parseInt(args[0]); //Where args[0] = "1000000"..
      int sum = 0;
      long R;

      for (int i = 1; i <= N; i++) {
      if (Main.isOverflowOrUnderflow(i, i)) {
      System.err.println("Overflow at i = " + i);
      System.exit(1);
      }

      R = i * i;
      sum += R;
      }

      System.out.println(sum);
      }

      public static boolean isOverflowOrUnderflow(int a, int b) {
      return ((a > Integer.MAX_VALUE / b) || (a < Integer.MIN_VALUE / b) || ((a == -1) && (b == Integer.MIN_VALUE)) || ((b == -1) && (a == Integer.MIN_VALUE)));
      }
      }


      Outputs:



      Overflow at i = 46341
      Command exited with non-zero status 1





      share|improve this answer




























        0












        0








        0







        Without having to use longs, you can check if the multiplication of two integers will overflow before actually doing the operation:



        int a = 500000; //or -500000
        int b = 900000; //or -900000

        System.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) {
        return ((a > Integer.MAX_VALUE / b) || (a < Integer.MIN_VALUE / b) || ((a == -1) && (b == Integer.MIN_VALUE)) || ((b == -1) && (a == Integer.MIN_VALUE)));
        }


        Example using your code:



        public class Main {
        public static void main (String args) {
        int N = Integer.parseInt(args[0]); //Where args[0] = "1000000"..
        int sum = 0;
        long R;

        for (int i = 1; i <= N; i++) {
        if (Main.isOverflowOrUnderflow(i, i)) {
        System.err.println("Overflow at i = " + i);
        System.exit(1);
        }

        R = i * i;
        sum += R;
        }

        System.out.println(sum);
        }

        public static boolean isOverflowOrUnderflow(int a, int b) {
        return ((a > Integer.MAX_VALUE / b) || (a < Integer.MIN_VALUE / b) || ((a == -1) && (b == Integer.MIN_VALUE)) || ((b == -1) && (a == Integer.MIN_VALUE)));
        }
        }


        Outputs:



        Overflow at i = 46341
        Command exited with non-zero status 1





        share|improve this answer















        Without having to use longs, you can check if the multiplication of two integers will overflow before actually doing the operation:



        int a = 500000; //or -500000
        int b = 900000; //or -900000

        System.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) {
        return ((a > Integer.MAX_VALUE / b) || (a < Integer.MIN_VALUE / b) || ((a == -1) && (b == Integer.MIN_VALUE)) || ((b == -1) && (a == Integer.MIN_VALUE)));
        }


        Example using your code:



        public class Main {
        public static void main (String args) {
        int N = Integer.parseInt(args[0]); //Where args[0] = "1000000"..
        int sum = 0;
        long R;

        for (int i = 1; i <= N; i++) {
        if (Main.isOverflowOrUnderflow(i, i)) {
        System.err.println("Overflow at i = " + i);
        System.exit(1);
        }

        R = i * i;
        sum += R;
        }

        System.out.println(sum);
        }

        public static boolean isOverflowOrUnderflow(int a, int b) {
        return ((a > Integer.MAX_VALUE / b) || (a < Integer.MIN_VALUE / b) || ((a == -1) && (b == Integer.MIN_VALUE)) || ((b == -1) && (a == Integer.MIN_VALUE)));
        }
        }


        Outputs:



        Overflow at i = 46341
        Command exited with non-zero status 1






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 14 '18 at 1:57

























        answered Nov 14 '18 at 1:45









        BrandonBrandon

        13.2k750121




        13.2k750121






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53291614%2fjava-manual-overflow-handling-undesired-output%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Xamarin.iOS Cant Deploy on Iphone

            Glorious Revolution

            Dulmage-Mendelsohn matrix decomposition in Python