Converting long to int gives 0 - java

I have been testing out with this snippet of code:
public class Test {
public static int longToInt(long num) {
return (int) (num);
}
public static void main(String[] args) {
System.out.println(longToInt(100000000L));
}
}
I ran it but longToInt only returned 0. What is going on?

Casting a long to an int is done by removing the top 32 bits of the long. If the long value is larger than Integer.MAX_VALUE (2147483647) or smaller than Integer.MIN_VALUE (-2147483648), the net effect is that you lose significant bits, and the result is "rubbish".
Having said that, the code you supplied does not behave like you say it does ... if you compile and run it correctly. The original version should print an unexpected number ... but not zero. The modified version should print 1000000 as expected.
... is there a way I can store a long number larger than Integer.MAX_VALUE inside an int number?
No.
Well strictly yes ... in some circumstances. You could do something to map the numbers, For example, if you know that your numbers are always in the range A to B, and B - A is less than 232, then you could map a long in that range to an int by subtracting A from it.
However, it is mathematically impossible to define such a mapping if the size of the domain of numbers you are storing in the long is larger than 232. Which it typically is.

because, the long you gave doesn't fit into int. Give a smaller long and try !
int (32 bits)
long (64 bits)

Related

Storing result of multiplication of two integers in long

I solved a programming question where I had to find the number of 1's in the binary form of the product if 2 numbers A and B. The range of A and B was [0, 10^9] inclusive.
Here is the code I wrote.
public class Solution {
public static void main(String[] args) {
// System.out.println(solution(32329,4746475));
System.out.println(solution(3,4));
}
public static int solution(int A, int B) {
// write your code in Java SE 8
long mul=A*B;
int ans=0;
while(mul>0)
{
if((mul%2)!=0)
{
ans++;
}
mul=mul/2;
}
return ans;
}
}
This worked fine for the input (3,4) but, when I tried (32329,4746475) as input instead the code didn't work and it showed 0 as answer.
I put in a few output statements at different places to debug and found that with this input, the result of multiplication comes out to be -1170032381 (which is wrong) and therefore, the while loop's condition fails. So, I type-casted both A and B like so
long mul=(long)A*(long)B;
And voila it worked. Now, my question is why?
Why did the code work fine for smaller inputs and flop for larger ones and shouldn't 'int to long' be implicit type casting in Java?
(I also tried a few other inputs so not all larger ones give negative as the product but they don't give the correct answer either, smaller ones I've tried till 5-digit A and B give the correct product)
Java has automatic widening from int to long, but that happens at assignment, but the multiplication of an int with another int produces an int, so you would get integer overflow first multiplying 32329 with 4746475, then the widening of the overflowed int result to long.
However, if you first cast at least one of the int to long, then the multiplication is done using long and the result is long, so no integer overflow.
Java int can store from
-2147483648 to 2147483647
32329 X 4746475 =153448790275
as Java does the multiplication before the implicit conversion the result is wrong

Multiply an int in Java by itself

Why if I multiply int num = 2,147,483,647 by the same int num is it returning 1 as result? Note that I am in the limit of the int possible value.
I already try to catch the exception but still give the result as 1.
Before any multiplication java translates ints to binary numbers. So you are actually trying to multiply 01111111111111111111111111111111 by 01111111111111111111111111111111. The result of this is something like
1111111111111111111111111111111000000000000000000000000000000001. The int can hold just 32 bits, so in fact you get 00000000000000000000000000000001 which is =1 in decimal.
In integer arithmetic, Java doesn't throw an exception when an overflow occurs. Instead, it just the 32 least significant bits of the outcome, or equivalently, it "wraps around". That is, if you calculate 2147483647 + 1, the outcome is -2147483648.
2,147,483,647 squared happens to be, in binary:
11111111111111111111111111111100000000000000000000000000000001
The least significant 32 bits of the outcome are equal to the value 1.
If you want to calculate with values which don't fit in 32 bits, you have to use either long (if 64 bits are sufficient) or java.math.BigInteger (if not).
int cannot handle just any large value.Look here. In JAVA you have an exclusive class for this problem which comes quite handy
import java.math.BigInteger;
public class BigIntegerDemo {
public static void main(String[] args) {
BigInteger b1 = new BigInteger("987654321987654321000000000"); //change it to your number
BigInteger b2 = new BigInteger("987654321987654321000000000"); //change it to your number
BigInteger product = b1.multiply(b2);
BigInteger division = b1.divide(b2);
System.out.println("product = " + product);
System.out.println("division = " + division);
}
}
Source : Using BigInteger In JAVA
The Java Language Specification exactly rules what should happen in the given case.
If an integer multiplication overflows, then the result is the low-order bits of the mathematical product as represented in some sufficiently large two's-complement format. As a result, if overflow occurs, then the sign of the result may not be the same as the sign of the mathematical product of the two operand values.
It means, that when you multiply two ints, the result will be represented in a long value first (that type holds sufficient bits to represent the result). Then, because you assign it to an int variable, the lower bits are kept for your int.
The JLS also says:
Despite the fact that overflow, underflow, or loss of information may occur, evaluation of a multiplication operator * never throws a run-time exception.
That's why you never get an exception.
My guess: Store the result in a long, and check what happens if you downcast to int. For example:
int num = 2147483647;
long result = num * num;
if (result != (long)((int)result)) {
// overflow happened
}
To really follow the arithmetics, let's follow the calculation:
((2^n)-1) * ((2^n)-1) =
2^(2n) - 2^n - 2^n + 1 =
2^(2n) - 2^(n+1) + 1
In your case, n=31 (your number is 2^31 - 1). The result is 2^62 + 2^32 + 1. In bits it looks like this (split by the 32bit boundary):
01000000000000000000000000000001 00000000000000000000000000000001
From this number, you get the rightmost part, which equals to 1.
It seems that the issue is because the int can not handle such a large value. Based on this link from oracle regarding the primitive types, the maximum range of values allowed is 2^31 -1 (2,147,483,647) which is exactly the same value that you want to multiply.
So, in this case is recommended to use the next primitive type with greater capacity, for example you could change your "int" variables to "long" which have a bigger range between -2^63 to 2^63-1 (-9223372036854775808 to 9223372036854775807).
For example:
public static void main(String[] args) {
long num = 2147483647L;
long total = num * num;
System.out.println("total: " + total);
}
And the output is:
total: 4611686014132420609
I hope this can help you.
Regards.
According to this link, a Java 'int' signed is 2^31 - 1. Which is equal to 2,147,483,647.
So if you are already at the max for int, and if you multiply it by anything, I would expect an error.

Arithmetic Operation in Java

Assume that I have one arithmetic function which will add two long variables and return a long value. If pass Long.MaxValue() as an argument it wont give a perfect result. What will be the solution for that? The code below explains what I mean:
public class ArithmaticExample {
public static void main(String[] args) {
System.out.println(ArithmaticExample.addLong(Long.MAX_VALUE, Long.MAX_VALUE));
}
public static long addLong(long a,long b){
return a+b;
}
}
So you can see the wood from the trees, let's recast the problem using byte rather than long and consider
byte a = 0b01111111; // i.e. 127, the largest value of a `byte`.
byte b = 0b01111111;
byte c = (byte)(a + b);
where you need the explicit cast to circumvent conversion of a + b to an int.
Computing c by hand gives you 0b11111110. This is, of course, the bitwise representation of -2 in an 8 bit 2's complement type.
So the answer for the byte case is -2. And the same holds true for a long: there are just more 1 bits to contend with in your addition.
Note that although all this is perfectly well-defined in Java, the same cannot be said for C and C++.
If you need to add two long values of such magnitude then consider using BigInteger.
The result is -2. This is not what is expected as it seems to be more an overflow than anything else, but this result is "normal".
Long.MAX_VALUE = 9223372036854775807
Long.MAX_VALUE + 1 = 9223372036854775807
Long.MAX_VALUE + Long.MAX_VALUE = -2

Java - Multiplication not working as expected

the below code gives me -1894967296 as result but this is not expected. What is exactly happening? I can't figure it out. The result has to be 2400000000 as per my calculator :(
import java.util.List;
import java.util.ArrayList;
public class Calculate{
public static void main(String []args){
int result = 1;
List<Integer> integer = new ArrayList<Integer>();
integer.add(100);
integer.add(200);
integer.add(300);
integer.add(400);
for (Integer value : integer) {
result *= value;
}
System.out.println(result);
}
}
When I debug, it works correctly till the third iteration.
Update:
As per the answers, the int primitive type range has been exceeded but what will happen to the int variable? It will be defaulted to some value?
The largest number Java can store in an int is 2^31 - 2147483648
2400000000 is larger than that so "wraps around".
You need to use a 64 bit data type such as long.
2400000000 is too large to store in an int. It would be more appropriate to use a long which has a minimum value of -2^63 and maximum value of 2^63 - 1 which your number is well within the range of.
more info here
The expected result 2400000000 > Integer.MAX_VALUE. So, use long instead of int to store result.
Use BigInteger instead of int because the int is limited
Java doc:
int: By default, the int data type is a 32-bit signed two's complement integer, which has a > minimum value of -231 and a maximum value of 231-1. In Java SE 8 and later, you can use the int data type to represent an unsigned 32-bit integer, which has a minimum value of 0 and a maximum value of 232-1. Use the Integer class to use int data type as an unsigned integer. See the section The Number Classes for more information. Static methods like compareUnsigned, divideUnsigned etc have been added to the Integer class to support the arithmetic operations for unsigned integers.
That's what most programmer call Pillage. You shouldn't save a long value inside a small variable, don't expect an Int to save a value 2^31+.
For what you want to do there's a long

what is 0x00FFFFFFFFFFFFFFL?

Hi i am trying to understand how the range encoder works so i found a java program for range encoder then when i was trying to reverse engineer the code where i came across the value 0x00FFFFFFFFFFFFFFL, i would appreciate if any one can tell why we use this value ?
public class RangeCoder64
{
static final protected long Top=1L<<48;
static final protected long Bottom=1L<<40;
static final protected long MaxRange=Bottom;
protected long Low=0;
protected long Range=0x00FFFFFFFFFFFFFFL;
}
0x represents the value is hexadecimal.
L indicates the literal is a long value.
Basically it's just a large number. (Decimal value is 72057594037927935)
0x00FFFFFFFFFFFFFFL is 0x + 00FFFFFFFFFFFFFF + L
0x denotes hex is used
00FFFFFFFFFFFFFF is hex for 72,057,594,037,927,935
L means that the value is of size Long -- smaller numbers do not need it (below size requiring Long)
When you see a value that is 1 less than a power of 2, it will be right filled with 1's and therefore in hex will be right filled with Fs. Genertally, it will be used as a mask, that mask when anded with a value will keep only the low bits, in this case it will discard the highest byte, and keep the 7 low bytes.
It would be the value of that range. It looks like 7 bytes. So for some reason it is restricting the number.

Categories

Resources