Java Multiple Two numbers issue with negative numbers [duplicate] - java

This question already has answers here:
Why I am getting -2147483648 and -1's multiplication, negative i.e. -2147483648, instead it should be +2147483648 [duplicate]
(1 answer)
How does Java handle integer underflows and overflows and how would you check for it?
(12 answers)
How are integers internally represented at a bit level in Java?
(10 answers)
Why does the negative of Integer.MIN_VALUE give the same value? [duplicate]
(2 answers)
Closed 2 years ago.
I’m recently facing the below problem
public class Main {
public static void main(String[] args) throws Exception {
// Your code here!
int i = -2147483648;
int j = i * -1;
System.out.println("j="+j);
}
}
Result : -2147483648
Online IDE with code :
https://paiza.io/projects/e/17lF_6-GltIcyubZv3QoFg?theme=twilight
But how it’s works as per the logic I need to get 2147483648 is a result right?
Then how I got this negative number ?
It’s because of integer range (Integer.MIN_VALUE)?
how to fix this issue?

The maximum postive value an int can hold is 2147483647 beyond which the value goes to the other end (i.e. it starts from the negative end). You can understand it from the following demo:
public class Main {
public static void main(String[] args) {
int i = -2147483648;
int j = i * -1;
System.out.println("j=" + j);
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MAX_VALUE + 1);
System.out.println(Integer.MIN_VALUE);
// Some more examples for you to understand this concept better
System.out.println(Integer.MAX_VALUE + 2);
System.out.println(Integer.MAX_VALUE + 3);
}
}
Output:
j=-2147483648
2147483647
-2147483648
-2147483648
-2147483647
-2147483646
After -2147483648 is multipled with -1, it becomes 2147483648 but an int variable can not hold this much big positive value; so, it will start from the negative end (i.e. Integer.MIN_VALUE).

The number 2147483648 does not exists. The biggest value of an int is 2147483647, which is 1 smaller than your expected result. The multiplication causes an overflow, which 'rolls back' the number to the smallest negative value, and continues the calculation from there. (With other words: 2147483647+1=-2147483648 (smallest negative)) Since the result would only be 1 over the maximum value, there is no additional action required and the minimal int value is returned.
If you want to fix this issue, use 'long' instead of 'int' for your variables. You can also use more complex classes like BigDecimal, or write a custom multiplication function for byte arrays.
Note: no matter what numeric type you use, as long as the memory used for representing the number is finite you can run into similar issues. Although under normal circumstances it is unlikely, even for a 32-bit integer (int).

Related

Math.pow() returns [float]E[int] [duplicate]

This question already has answers here:
Java and decimals E numbers
(2 answers)
Closed 8 months ago.
I was working on some problem in codeforces just for practice and the implementation I came up with is based on using the Math.pow() method in Java:
import java.io.*;
import java.util.*;
public class TestClass {
public static void main(String[] args) {
MyScanner sc = new MyScanner();
out = new PrintWriter(new BufferedOutputStream(System.out));
long t = sc.nextLong();
//note that "MyScanner" is a pre-defined class for buffered input
//just to make it easier to call the methods
while (t-- > 0){
String m = sc.next();
long l = m.length(), n = Long.parseLong(m);
out.println(n - Math.pow(10, l-1));
}
out.close();
}
}
I/O example: the input can be too big, that's why I used the long datatype.
Input:
7
1
2
178
20
999999999
9000
987654321
Output:
0
1
78
10
899999999
8000
887654321
but instead I get this:
0.0
1.0
78.0
10.0
8.99999999E8
8000.0
8.87654321E8
as you can see, my solution seems to be correct, but the output was in different form.
The method you use has the following signature: static double pow(double a, double b). This means, the parameters will automatically be cast to double and it's return value is also a double.
There is no overload for a long return value so you will either have to cast the result manually to long with this: n - (long)Math.pow(10, l-1).
Edit: or use another solution like the BigInteger one, but be aware that BigInteger (and BigDecimal) only accepts int as exponent, not long and not BigInteger.
Math.pow won't guarantee 100% accuracy on large integer values beyond some threshold (see this question for details) because floats and doubles cannot accurately represent all integers supported by the long type. Therefore, I would recommend you to use a BigInteger, which also has a pow function and will give you correctly formatted results out of the box.

Problem with how does loops and Math.abs work [duplicate]

This code:
System.out.println(Math.abs(Integer.MIN_VALUE));
Returns -2147483648
Should it not return the absolute value as 2147483648 ?
Integer.MIN_VALUE is -2147483648, but the highest value a 32 bit integer can contain is +2147483647. Attempting to represent +2147483648 in a 32 bit int will effectively "roll over" to -2147483648. This is because, when using signed integers, the two's complement binary representations of +2147483648 and -2147483648 are identical. This is not a problem, however, as +2147483648 is considered out of range.
For a little more reading on this matter, you might want to check out the Wikipedia article on Two's complement.
The behaviour you point out is indeed, counter-intuitive. However, this behaviour is the one specified by the javadoc for Math.abs(int):
If the argument is not negative, the argument is returned.
If the argument is negative, the negation of the argument is returned.
That is, Math.abs(int) should behave like the following Java code:
public static int abs(int x){
if (x >= 0) {
return x;
}
return -x;
}
That is, in the negative case, -x.
According to the JLS section 15.15.4, the -x is equal to (~x)+1, where ~ is the bitwise complement operator.
To check whether this sounds right, let's take -1 as example.
The integer value -1 is can be noted as 0xFFFFFFFF in hexadecimal in Java (check this out with a println or any other method). Taking -(-1) thus gives:
-(-1) = (~(0xFFFFFFFF)) + 1 = 0x00000000 + 1 = 0x00000001 = 1
So, it works.
Let us try now with Integer.MIN_VALUE . Knowing that the lowest integer can be represented by 0x80000000, that is, the first bit set to 1 and the 31 remaining bits set to 0, we have:
-(Integer.MIN_VALUE) = (~(0x80000000)) + 1 = 0x7FFFFFFF + 1
= 0x80000000 = Integer.MIN_VALUE
And this is why Math.abs(Integer.MIN_VALUE) returns Integer.MIN_VALUE. Also note that 0x7FFFFFFF is Integer.MAX_VALUE.
That said, how can we avoid problems due to this counter-intuitive return value in the future?
We could, as pointed out by #Bombe, cast our ints to long before. We, however, must either
cast them back into ints, which does not work because
Integer.MIN_VALUE == (int) Math.abs((long)Integer.MIN_VALUE).
Or continue with longs somehow hoping that we'll never call Math.abs(long) with a value equal to Long.MIN_VALUE, since we also have Math.abs(Long.MIN_VALUE) == Long.MIN_VALUE.
We can use BigIntegers everywhere, because BigInteger.abs() does indeed always return a positive value. This is a good alternative, though a bit slower than manipulating raw integer types.
We can write our own wrapper for Math.abs(int), like this:
/**
* Fail-fast wrapper for {#link Math#abs(int)}
* #param x
* #return the absolute value of x
* #throws ArithmeticException when a negative value would have been returned by {#link Math#abs(int)}
*/
public static int abs(int x) throws ArithmeticException {
if (x == Integer.MIN_VALUE) {
// fail instead of returning Integer.MAX_VALUE
// to prevent the occurrence of incorrect results in later computations
throw new ArithmeticException("Math.abs(Integer.MIN_VALUE)");
}
return Math.abs(x);
}
Use a integer bitwise AND to clear the high bit, ensuring that the result is non-negative: int positive = value & Integer.MAX_VALUE (essentially overflowing from Integer.MAX_VALUE to 0 instead of Integer.MIN_VALUE)
As a final note, this problem seems to be known for some time. See for example this entry about the corresponding findbugs rule.
Here is what Java doc says for Math.abs() in javadoc:
Note that if the argument is equal to
the value of Integer.MIN_VALUE, the
most negative representable int value,
the result is that same value, which
is negative.
To see the result that you are expecting, cast Integer.MIN_VALUE to long:
System.out.println(Math.abs((long) Integer.MIN_VALUE));
There is a fix to this in Java 15 will be a method to int and long. They will be present on the classes
java.lang.Math and java.lang.StrictMath
The methods.
public static int absExact(int a)
public static long absExact(long a)
If you pass
Integer.MIN_VALUE
OR
Long.MIN_VALUE
A Exception is thrown.
https://bugs.openjdk.java.net/browse/JDK-8241805
I would like to see if either Long.MIN_VALUE or Integer.MIN_VALUE is passed a positive value would be return and not a exception but.
2147483648 cannot be stored in an integer in java, its binary representation is the same as -2147483648.
But (int) 2147483648L == -2147483648 There is one negative number which has no positive equivalent so there is not positive value for it. You will see the same behaviour with Long.MAX_VALUE.
Math.abs doesn't work all the time with big numbers I use this little code logic that I learnt when I was 7 years old!
if(Num < 0){
Num = -(Num);
}

Why does a fraction stored in a double become a whole number upon outputting to screen? [duplicate]

This question already has answers here:
Division of integers in Java [duplicate]
(7 answers)
Closed 6 years ago.
So, I have this code which is the beginning of an RSA-encrypter (current math class). Now I'm still in the beginning stages and I notice that when I try to make an array of doubles, they all come out to the screen as whole numbers, what's going on here ?
As you can see in the code I divide the multiples of 7 by 40 and it should come out as fractions (7 / 14 = 0.175 for example) but instead as 0.0.
Help
import java.util.*;
public class Encryption {
static double[] ads = new double[200];
public static void main(String args[]){
for(int i = 0; i < 200; i++){
ads[i] = (7 * i) / 40;
}
for(int i = 0; i < ads.length; i++){
System.out.println(ads[i]);
}
}
}
It's because you're storing an integer into the array in the first place.
Consider this line:
ads[i] = (7 * i) / 40;
In the expression on the right, you first multiply i by 7, then divide it by 40. i is an integer. So, let's say i == 1. Then, 7 * i == 7, which is still an integer. Both 7 and 40 are integers, so when you evaluate 7 / 40, you get integer division. Integer division always rounds down. When the result gets stored into ads[i], it gets converted to a double, but by that point it's already been rounded down.
Try changing this line to the following:
ads[i] = (7 * i) / 40.0;
This works because 40.0 is a double, not an int.
In unrelated news, if you're using double to implement RSA, you're probably doing something wrong. Doubles aren't infinitely precise, and will screw up your result.

Java casting (cast operator expressions) [duplicate]

This question already has answers here:
Integer division: How do you produce a double?
(11 answers)
Closed 6 years ago.
The question require me to write a Java program to show the results of the following cast operator expressions:
(double) (23 / 14) + 7.65
My Code:
public class op {
public static void main(String [] args) {
int num = 23/14;
double r1 = (double) num;
double result = r1 + 7.65;
System.out.println("Results: "+ result);
}
}
I don't think I have done correctly, what are the problems of my code?
By the way, can someone tell me what are the differences between long, double, int, float? How do we know when to use these primitive data types? I read an explanation here: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
but is there any 'human-version' of the explanation?
Thank you for your help.
The problem is due to the used types.
Since you divide two integers (23 and 14), the result is considered and int as well. Therefor, 23/14 = 1.642857142857143, which is truncated to fit in an int result, more specifically, 1.
result is the sum of 1 (int) and 7.65 (double). Since one of them is a double, to other is converted to the "upper" type as well (double) and the operation becomes 1.0+7.65 = 8.65.
The result is correct, because you asked the result of (double) (23 / 14) + 7.65 which means the result of casting the result of the operations in brackets to double summed with 7.65. Which is 8.65 as previously explained.
If you want to use a division using doubles, consider:
double r1 = 1.0 * 23/14;
Lets see step-by-step:
int num = 23/14; // int division of 23/14 results in 1
So, here num = 1
When you cast num to double value of r1 is setted to 1.0.
double result = r1 + 7.65; //1.0 + 7.65 = 8.65
ok, int is short term for INTEGER which are natural numbers that we use normally but with no decimal places and if your number has some value in between roughly -2 billion to +2 billion. if your range exceeds that and you still want an integer then go for long data type.
floats are for decimal values like 3.147 with a range of +10*38 to -10*38 or so, but if your range exceeds this(practically this happens rarely) go for double.
coming to the code you put here , if you divide a int by another int (like 23/14) you get only get the integer part of the answer(only '1' in 23/14=1.642...) , next when you cast it to double you get 1.0 and next you are going to add that to 7.65 which will make the ultimate answer as 8.65 hope this answers your Q....
You could change this int num = 23/14
to double num = ((double) 23)/14
or double num = (23 * 1.0)/14

Project euler 10 help. Whats wrong with this code? the sum flips to negative [duplicate]

This question already has answers here:
How does Java handle integer underflows and overflows and how would you check for it?
(12 answers)
Closed 8 years ago.
// finding sum of all primes under 2 million
public class lll {
public static void main(String[] args) {
int a = 2;
int b = 0;
int c = 0;
while (a < 2000000) {
int i = 1;
for (i = 1; i * i <= a; i++) {
if (a % i == 0)
//if factor is found of number a b goes up 1
{
b++;
}
}
// all primes have only one factor <= sqrt (1)
if (b == 1)
// if b =1 , a is prime so c+=a
{
c += a;
}
//reset b and add one to a to move on
b = 0;
a++;
// for error checking see description
System.out.println(c);
}
System.out.println(c);
}
}
Im trying to make a code to find the sum of all primes under 2 million, heres what i have it gives 1179908154, but this is not right, c is supposed to be the sum. I tried getting c after every check of number being prime and it shows that during the running of this code it lips from positive to negative and then back again. it makes no sense a starts at 1, a goes up c starts at 0, it goes up by a so how is c getting negative (a is never negative), please help me, I have managed to used this method of prime checking to correctly get the 10001st prime, it worked then.
A 32 bit integer can only hold numbers below about 2 billion. If you try to add more to that number (accessible by Integer.MAX_VALUE), you will end up "flipping" to negative numbers. Try out the following code:
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MAX_VALUE + 1);
System.out.println(Integer.MIN_VALUE);
So your problem is that integers aren't big enough! How can you solve this? The simplest way is to use a long instead of an int. Hypothetically, what if a long isn't even big enough? Then you can use a class like BigInteger, which isn't constrained to a fixed number of bits, and can grow as necessary.
Well, you declared c as an int which in java has a max value of 2,147,483,647 . The sum of all primes less than 1 million is 37,550,402,023, so Im thinking you are surpassing the data storage for int which is why its flipping negative on you.
My guess is that it has something to do with memory. In java the maximum number an integer can hold is 2147483647. So if the sum of primes goes over this number, it will loop back to -2147483648 and continue counting. Try making your variable c a long instead.

Categories