This question already has answers here:
How can I check if multiplying two numbers in Java will cause an overflow?
(15 answers)
Closed 4 years ago.
int a = 200000;
double b = (double) (a*a);
I would like to be able to calculate if (aa) (integers) is already too large (stackOverflow) to hold in the variable; in this case I know that multiplying (aa) leads to an int that will not fit -> the number will be wrong;
What I do not understand is how I can calculate this off the top of my head. How can I see if a value will not fit in an int variable??
Is there a way to do this without using methods, by just using the plain code and common sense? ;-)
Best regards,
Wouter
Two possible solutions.
Catch exception thrown after a call to the Math.…Exact methods: Math.multiplyExact, Math.addExact, Math.decrementExact, and so on.
int a = 200000;
try {
int result = Math.multiplyExact(x, y);
} catch(ArithmeticException e) {
//if you get here, it is too big
}
Or, check against the constants for minimum and maximum possible integer values.
long test = (long)a*(long)a;
if (test > Integer.MAX_VALUE || test < Integer.MIN_VALUE)
// Overflow!
You could make use of the constant MAX_VALUE from the Integer wrapper class and cast to long instead (you will get a compile error if you cast to double but exceed it's range)
int a = 200000;
long b = (long) a * (long) a;
if (b > Integer.MAX_VALUE) {
// do something
}
MAX_VALUE corresponds to the highest value an integer can be, (2^31)-1
Related
This question already has answers here:
How to test if a double is an integer
(18 answers)
Closed 3 years ago.
I'm getting a value of type double from an API which, in my specific case, should always return a whole number in a range well within int's — any non-whole number will mean something went very wrong inside that API call. I do want to know when this happens.
I know I can do a post-conversion check like, let say:
double value = …;
int whole_number = (int) value;
if(value != whole_number) throw …;
Is there any shorter idiom to "Convert a double to int only if it is an exact conversion, and raise an exception if not"?
Your solution seems simplest to me. You can do it as a one-liner:
if (value != (int)value)) throw ...
but if you want the exception to be thrown for you, the only thing I can think of is to go through a String, which seems really convoluted, especially since you can't just use String.valueOf(value) to get the string:
// Seems really convoluted
Integer.parseInt(new DecimalFormat("##.###").format(d));
You can use the following check if needed
if (value % 1 != 0) {
throw...
}
Using an Optional<Double> you could use the following logic
Integer result = Optional.of(value)
.filter(d -> d % 1 == 0)
.filter(this::isInRange)
.map(Integer::parseInt)
.orElseThrow(...);
You can use BigDecimal::intValueExact():
int wholeNumber = BigDecimal.valueOf(value).intValueExact();
It will automatically throw an exception: if it has a nonzero fractional part or it is outside the range of int
This question already has answers here:
How does Java handle integer underflows and overflows and how would you check for it?
(12 answers)
Closed 7 years ago.
I wrote a program to store Fibonacci numbers and will retrieve the nth Fibonacci number. It works fine until the 50th Fibonacci where it returns a negative number.
getFibonacci(47) returns 1836311903 but
getFibonacci(48) returns -1323752223. Why is this?
public class Fibonacci {
static HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
public static void main(String[] args) {
int x;
storeFibonacciNumbers(50);
System.out.println(getFibonacci(48));
}
public static void storeFibonacciNumbers (int n){
for (int x=1; x <= n; x++ ){
if(x == 1){
map.put(x, 0);
}
else if (x == 2) {
map.put(x, x-1);
}
else
map.put(x, map.get(x-1) + map.get(x-2));
}
}
public static long getFibonacci (int x){
return map.get(x);
}
}
This is because the maximum value of an Integer has been reached. When you try to add a value to it, it overflows, and "wraps around" to the negative.
An alternative is to use a type that supports higher maximums (e.g. Long).
At some point, you might be forced to switch to types that are more complex, but are built specifically to store very large integers (e.g. BigInteger).
In the HashMap you are storing Fibonacci number as a Integer. The maximum value that an Int can hold is 2147483647 (2^31-1)
So based on your calculations Fibonacci(47) must exceed that maximum value and overflow is happening.
Change your HashMap value type to Long. It will fix your problem.
An Integer Overflow is the condition that occurs when the result of an arithmetic operation, such as multiplication or addition, exceeds the maximum size of the integer type used to store it.
It's because the int type only goes so high. The max value is 2147483647, at which point it will just start over. You need to use a different datatype, such as a long if you want to represent a bigger number correctly.
The max java integer is 2^31-1 or 2147483647. After you reach that value you will start returning negative numbers.
You can use the constant Integer.MAX_VALUE as a way to stop your program once you reach that value.
This is called Integer Overflow, and occurs when a number increments over/falls under its maximal/minimal (memory) bounds (for java.lang.Integer this would be -2^31 and 2^31-1)
This question already has answers here:
Multiplication of two ints overflowing to result in a negative number
(5 answers)
Closed 9 years ago.
static int fn = 0;
static int sn = 0;
static boolean running = false;
public static void run()
{
while (running == true)
{
fn = numbers[0];
sn = numbers[1];
if (sign == 0)
{
input.setText(String.valueOf(fn));
}
}
}
static class one implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if (Display.sign == 0)
{
Display.numbers[0] = Display.numbers[0] *10;
Display.numbers[0] = Display.numbers[0] +1;
}
}
}
This is the code for a calculator that I am programming (not all of it of course). This is the part where I display the number on the screen which I have done, but weirdly this works up until 10 characters
So after I get the program to display 1111111111 I want to do it once more and it gives me this weird number -1773790777. I am confused about how the program comes up with this. As you can see, above Display.numbers[] is the array I am storing the two numbers in. So to go over a place I multiply the number in the array by 10 then add 1. So how does this give me a negative number in the first place and what can I do to solve this problem?
Is your number overflowing?
You can check it by looking at Integer.MAX_VALUE (assuming you are using an integer). If you go over that you will loop will get weird results like this. See - http://javapapers.com/core-java/java-overflow-and-underflow/ for more details.
It's overflowing!
1111111111*10 + 1 = 11111111111 which is 0x2964619C7 in hexadecimal. It's a 34-bit value which can't be stored in a 32-bit int
In Java arithmetic operations wrap around by default, so if the result overflowed then it'll be wrapped back to the other end of the value range. See How does Java handle integer underflows and overflows and how would you check for it?
However due to the use of 2's complement, the result will be the lower bits of the result 11111111111 mod 232 = 2521176519 = 0x964619C7 which is -1'773'790'777 in 32-bit int, that's why you see the number. You should read more on binary, that's the basic of nowadays computers
In Java 8 you'll have an easier way to detect overflow with the new *Exact methods
The platform uses signed two's complement integer arithmetic with int and long primitive types. The developer should choose the primitive type to ensure that arithmetic operations consistently produce correct results, which in some cases means the operations will not overflow the range of values of the computation. The best practice is to choose the primitive type and algorithm to avoid overflow. In cases where the size is int or long and overflow errors need to be detected, the methods addExact, subtractExact, multiplyExact, and toIntExact throw an ArithmeticException when the results overflow. For other arithmetic operations such as divide, absolute value, increment, decrement, and negation overflow occurs only with a specific minimum or maximum value and should be checked against the minimum or maximum as appropriate.
https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can I check if multiplying two numbers in Java will cause an overflow?
Suppose I have a Java class method, which uses * and + operations.
int foo(int a, int b) {
... // some calculations with + and *
}
How to make sure that no overflow occurs in foo?
I guess I can either use BigDecimal or replace all + and * with "wrappers" like:
int sum(int a, int b) {
int c = a + b;
if (a > 0 && b > 0 && c < 0)
throw new MyOverfowException(a, b)
return c;
}
int prod(int a, int b) {
int c = a * b;
if (a > 0 && b > 0 && c < 0)
throw new MyOverfowException(a, b)
return c;
}
Are there better ways to make sure that no int overflow occurs in a Java method ?
One way to check for an overflow is to have the operands promoted to a larger type (of double the original operand bit length) then perform the operation, and then see if the resulting value is too large for the original type, e.g.
int sum(int a, int b) {
long r = (long)a + b;
if (r >>> 32 != 0) { // no sign extension
throw new MyOverflowException(a, b);
}
return (int)r;
}
If your original type is a long, you'd have to use BigInteger as that larger type.
It is a difficult problem from an engineering perspective.
The Secure Coding site recommends:
use of preconditions; i.e. range-check the inputs so that overflow is impossible,
doing each individual arithmetic operation using the next larger primitive integer type and explicitly checking for overflow, or
using BigInteger.
This Dr Dobbs article suggests creating a library of primitive arithmetic methods that do each primitive operation with an explicit overflow check. (You could view this as an implementation of bullet point #2 above.) But the authors go further by suggesting that you use bytecode rewriting to replace arithmetic bytecodes with calls to the equivalent methods which incorporate overflow checks.
Unfortunately, there is no way to enable overflow checking natively in Java. (But the same applies in lots of other languages; e.g. C, C++ ... )
Sum: Check whether b is larger than the difference of the maximum value you can store in int minus the value of a. If a and/or b can be negative, you must (i) be careful not to get an overflow already for the difference check and (ii) perform a similar check for the minimum.
Product: Thats more difficult. I would split the integers into two half-length integers (i.e. if int is 32 bit, split it into two 16 bit numbers using bit-masking and shifting). Then do the multiplication, and then look whether the result fits into 32 bit.
Everything under the condition that you do not want to simply take long for the temporary result.
Suppose both a and b are positive or negative, and if the sign of a + b is not equal with the sign of a and b, then overflow happens. You can use this rule to judge whether overflow happens and throw an exception. When you catch this expcetion, you can deal it according to the method metioned in previous answers.
Another method is to doing operation using largest range type which will not overflow. You can use long for the operation between Integers.
I'm having problems detecting if a sum/multiplication of two numbers exceeds the maximum value of a long integer.
Example code:
long a = 2 * Long.MAX_VALUE;
System.out.println("long.max * smth > long.max... or is it? a=" + a);
This gives me -2, while I would expect it to throw a NumberFormatException...
Is there a simple way of making this work? Because I have some code that does multiplications in nested IF blocks or additions in a loop and I would hate to add more IFs to each IF or inside the loop.
Edit: oh well, it seems that this answer from another question is the most appropriate for what I need: https://stackoverflow.com/a/9057367/540394
I don't want to do boxing/unboxing as it adds unnecassary overhead, and this way is very short, which is a huge plus to me. I'll just write two short functions to do these checks and return the min or max long.
Edit2: here's the function for limiting a long to its min/max value according to the answer I linked to above:
/**
* #param a : one of the two numbers added/multiplied
* #param b : the other of the two numbers
* #param c : the result of the addition/multiplication
* #return the minimum or maximum value of a long integer if addition/multiplication of a and b is less than Long.MIN_VALUE or more than Long.MAX_VALUE
*/
public static long limitLong(long a, long b, long c)
{
return (((a > 0) && (b > 0) && (c <= 0))
? Long.MAX_VALUE
: (((a < 0) && (b < 0) && (c >= 0)) ? Long.MIN_VALUE : c));
}
Tell me if you think this is wrong.
If you can't be sure the result will be less than 9 trillion trillion, I would use double or BigInteger Getting an error doesn't help you very much because you still need to know what to do about.
Much better that you don't get an error in the first place by validating your input to ensure they are in range and if the range of the result is larger than long use a type which can handle this.
With BigInteger you can do
BigInteger a = BigInteger.valueOf(2).multiply(BigInteger.valueOf(Long.MAX_VALUE));
long l = a.longValue();
if (a.compareTo(BigInteger.valueOf(l)) == 0) {
// ok
} else {
// error
}
With double you can do
double d = 2.0 * Long.MAX_VALUE;
long l = (long) Math.max(Long.MIN_VALUE, Math.min(Long.MAX_VALUE, d));
// or as a helper method.
long l = boundedCast(d);
Note: using double instead of long can result in some loss of precision.
I would prefer to avoid the need for an error block in the first place.
Exceding the maximum value of a long doesnt throw an exception, instead it cicles back. If you do this:
Long.MAX_VALUE + 1
you will notice that the result is the equivalent to Long.MIN_VALUE
If you want it to throw an exception check if it reached the max value and throw the exception
[Edit]
You can also use the Guava Library to check if there is an overflow when you sum two longs;
long c = LongMath.checkedAdd(a, b);
this throws an exception when an overflow occurs.
You can find the javadoc here
Long values exceeding MAX_VALUE doesn't throw any exception. You need to check and handle such situations manually.
ALthough as #PeterLawrey suggested you should consider using double and BigInteger.