Java manual overflow handling undesired output
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
|
show 2 more comments
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
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. Ifi
is ever greater than that value, it'll overflow, no need to check further. Something likepublic 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
|
show 2 more comments
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
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
java
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. Ifi
is ever greater than that value, it'll overflow, no need to check further. Something likepublic 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
|
show 2 more comments
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. Ifi
is ever greater than that value, it'll overflow, no need to check further. Something likepublic 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
|
show 2 more comments
2 Answers
2
active
oldest
votes
You have 2 errors:
R = i * i
still performs the multiplication usingint
math, and doesn't widen the value tolong
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 thelong
value exceeds the range ofint
: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
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 usinglong 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 thesum
andi
variables. Of course, you could be right, since the point of thei != R / i
check would be thatR
is also anint
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
add a comment |
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
You have 2 errors:
R = i * i
still performs the multiplication usingint
math, and doesn't widen the value tolong
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 thelong
value exceeds the range ofint
: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
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 usinglong 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 thesum
andi
variables. Of course, you could be right, since the point of thei != R / i
check would be thatR
is also anint
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
add a comment |
You have 2 errors:
R = i * i
still performs the multiplication usingint
math, and doesn't widen the value tolong
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 thelong
value exceeds the range ofint
: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
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 usinglong 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 thesum
andi
variables. Of course, you could be right, since the point of thei != R / i
check would be thatR
is also anint
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
add a comment |
You have 2 errors:
R = i * i
still performs the multiplication usingint
math, and doesn't widen the value tolong
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 thelong
value exceeds the range ofint
: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
You have 2 errors:
R = i * i
still performs the multiplication usingint
math, and doesn't widen the value tolong
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 thelong
value exceeds the range ofint
: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
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 usinglong 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 thesum
andi
variables. Of course, you could be right, since the point of thei != R / i
check would be thatR
is also anint
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
add a comment |
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 usinglong 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 thesum
andi
variables. Of course, you could be right, since the point of thei != R / i
check would be thatR
is also anint
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
add a comment |
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
add a comment |
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
add a comment |
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
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
edited Nov 14 '18 at 1:57
answered Nov 14 '18 at 1:45
BrandonBrandon
13.2k750121
13.2k750121
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 likepublic 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