This question already has answers here:
How can I detect integer overflow on 32 bits int?
(5 answers)
Closed 2 years ago.
I am new in java language, here is m not able to understand, why program returning -2 after adding two full range integers.
class Variables {
public static void main(String[] args) {
int a = 2147483647;
int b = 2147483647;
long c = a + b;
System.out.println( c );
}
}
I am expacting 4294967294 value in my variable c, but why it returns -2
please explain me the reason behind this
You reach Integer.MAX_VALUE so you're going to -2147483648, then adding Integer.MAX_VALUE again will result in -2
To get 4294967294, you need to cast one value as long before to do a long sum and not an int one
int a = 2147483647;
System.out.println(a + 1); //-2147483648
int b = 2147483647;
System.out.println(a + b); // -2
long c = a + (long) b; // or ((long) a) + b;
System.out.println(c); //4294967294
The result of adding two ints is an int, which of course overflows when you add a and b. Only then is it promoted to a long.
You can get the result you expected by casting one of them to long before performing the addition:
long c = ((long) a) + b;
Related
This question already has answers here:
How Does Modulus Divison Work
(19 answers)
Closed 5 years ago.
package PracticePackage;
public class whileLoop {
public static void main(String[] args) {
int i=1;
System.out.println("Quotient "+i/2);
System.out.println("Remainder "+i%2);
}
}
this is the fomula that Java uses to yield the remainder of its operands:
(a/b)*b+(a%b)
where a is the dividend and b is the divisor.
so in your case it's like:
int i = 1;
int b = 2;
int result = (i / b) * b + (i % b);
hence the result 1 rather than 0
1/2 = 0.5
you defined i as int
Integral division in java takes floor of the answer if the answer is a real number so 1/2 becomes 0, making 1%2 equal to 1
I hope that explains.
because integers are not real numbers so you get 1 as answer and the real part of remainder is ignored since you defined i as an integer
I transfer the modExp function from int to BigInteger, but the result is different, what the different of these two functions?
Thanks!!!
The function with BigInteger, the result always 1:
public static BigInteger modExp(BigInteger a, BigInteger b, BigInteger n) {
BigInteger two = new BigInteger("2");
if (b == BigInteger.ZERO)
return BigInteger.ONE;
BigInteger t = modExp (a, b.divide(two), n);
BigInteger c = (t.pow(2)).mod(n);
if (b.mod(two) == BigInteger.ONE)
c = (c.multiply(a)).mod(n);
return c;
}
The function with int:
public static int modexp(int a, int b, int n) {
if (b == 0) return 1;
long t = modexp(a, b/2, n); // use long for intermediate computations to eliminate overflow
long c = (t * t) % n;
if (b % 2 == 1)
c = (c * a) % n;
return (int) c;
}
The function is to calculate a^b mod p, For example:
a=4 b=6 p=11 result1 = 1 result2 = 4
a=9 b=2 p=11 result1 = 1 result2 = 4
a=5 b=6 p=23 result1 = 1 result2 = 8 ...
The obvious difference is the difference between int and BigInteger.
One difference is that int is a primitive type and BigInteger is a reference type. As such, it is better to use equals() when comparing BigIntegers. So b == BigInteger.ZERO should be BigInteger.ZERO.equals(b).
BigInteger is more suited to working with big numbers and will prevent you running into problems with overflowing the max int value, supported by Java.
Overflowing may be the cause you are getting a different result from the two functions as well. When this occurs, it doesn't cause any exception to be thrown, but the values of the ints get messed up.
In java int can count from -2^31 up to 2^31-1 because int are coded over 4 bytes but long can count from -2^63 up to 2^63-1 because long are coded over 8 bytes.
In the second method with this :
return (int) c;
you may loose data (the 4 first byte)
That could explain why your result are different because BigInteger are coded over much more byte than long
This question already has answers here:
Difference between a += 10 and a = a + 10 in java? [duplicate]
(5 answers)
Closed 8 years ago.
I've been told that there are differences between a+=b; and a=a+b; which can result in only one of those being legal depending on the type declerations.
Does anyone have an example of this?
There is basically no difference, however there is a subtle difference.
The arithmetic assignment operators do an implicit cast. e.g.
byte a = 1;
int b = 2;
a += b; // compiles
a = a + b; // doesn't compile as a byte + int = int
a = (byte) (a + b); // compiles as this is the same as +=
For more weird examples.
int a = 5;
a += 1.5f;
// a == 6
char ch = '0'; // (char) 49
ch *= 1.1; // ch = '4';
long l = Integer.MAX_VALUE;
l += 0.0f; // i = (long ) ((long ) l + 0.0f)
// i == Integer.MAX_VALUE + 1L; WTF!?
// l is no longer Integer.MAX_VALUE due to rounding error.
The JLS (section 15.26.2) says:
A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T) ((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.
The presence of the type-cast means that there are a couple of edge cases where a = a op b means something different to a op= b.
See Peter Lawrey's answer for one example. It is when a is a byte and b is an int and the "op" is +. The "gotcha" is a + b produces an int, which then can't be assigned to a ... without a typecast.
The same scenario applies with other types for a and b and for other arithmentic and bitwise operators.
int a = 10;
int b = 20;
a=a+b; // 30
a+=b; // 30
System.out.println(a);
Both will give the same answer.
I have written a simple Java program as shown here:
public class Test {
public static void main(String[] args) {
int i1 =2;
int i2=5;
double d = 3 + i1/i2 +2;
System.out.println(d);
}
}
Since variable d is declared as double I am expecting the result of this program is 5.4 but I got the output as 5.0
Please help me in understanding this.
i1/i2 will be 0. Since i1 and i2 are both integers.
If you have int1/int2, if the answer is not a perfect integer, the digits after the decimal point will be removed. In your case, 2/5 is 0.4, so you'll get 0.
You can cast i1 or i2 to double (the other will be implicitly converted)
double d = 3 + (double)i1/i2 +2;
i1/i2 when converted to int gives 0. ie. why you are getting 5.0. Try this :
public static void main(String args[])
{
int i1 =2;
int i2=5;
double d = 3 + (double)i1/(double)i2 +2;
System.out.println(d);
}
This line is done in parts:
double d = 3 + i1/i2 +2;
double d = 3 + (i1/i2) +2;
double d = 3 + ((int)2/(int)3) +2;
double d = 3 + ((int)0) +2;
double d = (int)5;
double d = 5;
The double just means that the answer will be cast to a double, it doesn't have any effect till the answer is computed. You should write
double d = 3d + (double)i1/i2 +2d; //having one double in each "part" of the calculation will force it to use double maths, 3d and 2d are optional
i1/i2 will be 0 because both i1 and 12 are integers.
if you cast i1 or i2 to double then it will give the desired output.
double d = 3 + (double)i1/i2 +2;
This link provides information about data type conversion, both implicit and explicit type.
To provide exact answer to the question will be :
double d = 3 + (double)i1/i2 + 2
int i1 =2;
int i2=5;
double d = 3 + (double)i1/(double)i2 +2;
if i1/i2 will be fractional value then double will help it to be in fraction instead of int.
so now you will the result as you want. or you can also use following code
double d = 3+(double)i1/i2+2;
In this line i1 is converted into double which will be divided with i2 and result will be in double, so again result will be as 5.4
Since i1=2 and i2=5 are integer type and when you divide (2/5) them, It gives integer value (0) because fractional part(.4) get discarded.
So put (double)i1/i2 on the equation.
Why do the following two operations yield different results in Java for x = 31 or 32 but the same results for x=3?
int x=3;
int b = (int) Math.pow(2,x);
int c = 1<<x;
Results:
x=32: b=2147483647; c=1;
x=31: b=2147483647; c=-2147483648;
x=3: b=8 ; c=8
There are multiple issues at play:
An int can only store values between -2147483648 and 2147483647.
1 << x only uses the lowest five bits of x. Thus, 1 << 32 is by definition the same as 1 << 0.
Shift operations are performed on the two's-complement integer representation of the value of the left operand; this explains why 1 << 31 is negative.
Math.pow(2, 32) returns a double.
(int)(d), where d is a double greater than 2147483647 returns 2147483647 ("the largest representable value of type int").
What this interview question does is show that (int)Math.pow(2, x) and 1 << x are not equivalent for values of x outside the 0...30 range.
P.S. It is perhaps interesting to note that using long in place of int (and 1L in place of 1) would give yet another set of results different from the other two. This holds even if the final results are converted to int.
According to the documentation Math.pow will promote both of its arguments to double and return double. Obviously when the returned result is double and you cast it to int you'll get only the highest 32 bits and the rest will be truncated - hence you always get the (int) Math.pow(2,x); value. When you do bitshift you always work with ints and hence an overflow occurs.
Consider the limits of the type int. How large a number can it hold?
Here's a micro-benchmark for the case of a long. On my laptop (2.8GHz), using shift instead of Math.pow is over 7x faster.
int limit = 50_000_000;
#Test
public void testPower() {
Random r = new Random(7);
long t = System.currentTimeMillis();
for (int i = 0; i < limit; i++) {
int p = r.nextInt(63);
long l = (long)Math.pow(2,p);
}
long t1 = System.currentTimeMillis();
System.out.println((t1-t)/1000.0); // 3.758 s
}
#Test
public void testShift() {
Random r = new Random(7);
long t = System.currentTimeMillis();
for (int i = 0; i < limit; i++) {
int p = r.nextInt(63);
long l = 1L << p;
}
long t1 = System.currentTimeMillis();
System.out.println((t1-t)/1000.0); // 0.523 s
}
int is 32 bits in size and since it is signed (by default), the first bit is used for the sign. When you shift left 31 bits, you get the Two's Compliment, which is -(2^32). When you shift left 32 bits, it just loops all the way back around to 1. If you were to do this shifting with longs instead of ints, you would get the answers you expect (that is until you shift 63+ bits).