How to print long primitive in Java [duplicate] - java

This question already has answers here:
Multiplication operation in Java is resulting in negative value
(4 answers)
Closed 6 years ago.
Relatively new to Java and possibly some stupid question. Here is the code:
long a = 3232235521L;
long b = 192 * 16777216 + 168 * 65536 + 0 * 256 + 1;
System.out.println("a="+a);
System.out.println("b="+b);
The output:
a=3232235521
b=-1062731775
According to Java documentation max value for long 2^63-1 and that is: 9223372036854775807. So for b, there is no overflow, so why b isn't 3232235521?

In line 2 of your code, all your operands are integers, which is why the results of the operations will also be an integer.
Since the result(3,232,235,521) will not fit inside an integer(max value being 2^31 - 1), this results in an integer overflow, which is why you are getting the negative result.
So, you will need to use Long literals to get an accurate result. Change Line 2 to the below code.
long b = 192L * 16777216L + 168L * 65536L + 0L * 256L + 1L;
The above code should give you the correct output.

You are using integer primitives during the math and it's only converted at the end, after the integer overflow. You might want to use 192L * 16777216L + 168L * 65536L + 0L * 256L + 1L;

You are only doing the conversion to long on the assignment - up until that point everything is an integer and that is why you are seeing an overflow halfway through your calculation.
The code should be:
long b = 192l * 16777216l + 168l * 65536l + 0l * 256l + 1l;

Related

What Happened in overflow of short vs log variables in Java

I am new to java, and I don't understand the differences between these two:
Lets init some variables for the overflow:
byte myByte = 100;
short myShort = 5000 ;
int myInt = 2_000_150_000;
I know whenever I got variable and arithmetic I need to do a casting with (long)
long myLong = (long)(50_000 + 10 * (long)(myByte + myShort + myInt));
long myLong2 =(long)(50_000 + 10 * (myByte + myShort + myInt));
sysout(myLong);
sysout(myLong2);
OUTPUT:
20001601000
-1473235480
but why do I need to do it outside two times?
for short type, this works differently:
short myShortTest = (short)(50_000 + 10*(short)(myByte + myInt +myShort));
short myShortTest2 = (short)(50_000 + 10*(myByte + myInt +myShort));
sysout(myShortTest);
sysout(myShortTest2);
OUTPUT
13800
13800
Whenever an overflow happens, an int will move to the other end of the boundary as seen in the output of the following program:
public class Main {
public static void main(String[] args) {
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MAX_VALUE + 1);
System.out.println(Integer.MIN_VALUE);
System.out.println(Integer.MIN_VALUE - 1);
}
}
Output:
2147483647
-2147483648
-2147483648
2147483647
In the case of test1, because of casting to long, the result of the intermediate calculation [10*(long)(myByte + myShort + myInt)] was stored as long which can accommodate the result without an overflow and hence you got the correct value.
In the case of test2, in lack of proper cast, the result of the intermediate calculation [10*(myByte + myShort + myInt)] was stored as int but the value overflew for int and hence you got the negative value.
Your first version reads: add up my variables, treat the result as a long, multiply by 10, add 50000 and treat that as a long.
Your second version reads: add up my variables (result is an int), multiply by 10 (which is still an int but might be overflown), add 50000 (still a possibly overflown int) and treat that as a long.
So your fist version starts to treat the sum as a long value and reserves sufficient memory while your second version does this step at the very end, working with lower memory until then.

Why does adding a sum to a long value lead to a subtraction?

I encountered a troublesome issue and I can't really explain to myself why it is appearing.
Basically I want to add time to a timestamp (a simple long).
I understand it the following. If I add time to a timestamp I end in the future. If I subtract time to the timestamp I end in the past.
In my example it is the other way around. If I add something to my timestamp it is reduced and if I subtract something is added.
public class MyClass {
public static void main(String args[]) {
static final int MONTH_IN_SECONDS = 2629743;
final long current = System.currentTimeMillis();
System.out.println("Current: " + current);
final long future = System.currentTimeMillis() + (MONTH_IN_SECONDS * 1000 * 3);
System.out.println("Addition: " + future);
final long past = System.currentTimeMillis() - (MONTH_IN_SECONDS * 1000 * 3);
System.out.println("Subtraction: " + past);
}
}
Result (compare the first 5 chars):
Current: 1582275101365
Addition: 1581574395774 // smaller than current even though it should be greater
Subtraction: 1582975806958 // great than current even though it should be smaller
Why does this happend? Does the term (MONTH_IN_SECONDS * 1000 * 3) overflow because it is only an Integer and thus the calculation does not work (or ends in a negative value)?
If I change the term to (MONTH_IN_SECONDS * 1000L * 3) it seems to work correctly. Is it because the complete term is casted to a long?
The problem is here:
(MONTH_IN_SECONDS * 1000 * 3)
That's integer multiplication that's overflowing, and resulting in a negative number:
System.out.println((MONTH_IN_SECONDS * 1000 * 3));
That outputs -700705592. You'd have to declare MONTH_IN_SECONDS as long, or otherwise change the expression so that the result is long-typed.
Does the term (MONTH_IN_SECONDS * 1000 * 3) overflow because it is
only an Integer and thus the calculation does not work (or ends in a
negative value)?
Month in seconds? Google says 2,630,000. (Though I see you have 2629743.)
2,630,000 * 1000 * 3 = 7,890,000,000
Integer.MAX_VALUE = 2^31 = 2,147,483,648
So yeah, it's an integer overflow.

Why variable of long type is giving different answer after casting and before casting in the following code as both are of type long?

byte byteChallenge = 68;
short shortChallenge = 190;
int intChallenge = 2147483647;
long longChallenge = (50000L + 10L * (byteChallenge + shortChallenge + intChallenge));
long longChallengeX = 50000L + 10L * ((long) byteChallenge + (long) shortChallenge + (long)
intChallenge);
System.out.println(longChallenge);
System.out.println(longChallengeX);
The output I'm getting is:
-21474783910
21474889050
The tricky part is int intChallenge = 2147483647 constant which is the maximum value for positive int (see Integer.MAX_VALUE).
When you perform byteChallenge + shortChallenge + intChallenge it is an int arithmetic statement which results in integer overflow. In your example the integer overflow result is a negative number.
When you perform (long) byteChallenge + (long) shortChallenge + (long) intChallenge it is long arithmetic. Since long supports much larger values than int there is no overflow.
In the first scenario, the sub-expression (byteChallenge + shortChallenge + intChallenge) is basically "byte + short + int". Java evaluates this part first, before multiplying by 10 and adding to 50000.
Since the sub-expression doesn't involve a long type, Java has no reason to make the result type of the expression long, so the first two operands is only promoted to int and the three ints are added together to give another int. This causes an overflow, making the result very negative.
In the second case, you explicitly cast all three operands to long before operating on them, so the type of the sub-expression is resolved to be long.
The lesson here is that nested expressions are treated the same as any other expressions. (byteChallenge + shortChallenge + intChallenge) doesn't get special treatment just because it is multiplied with a long. Its value is still evaluated the same way.

why long COOKIE_TIMEOUT = 1000 * 60 * 60 * 24 * 30 return negative? [duplicate]

This question already has answers here:
Multiplication operation in Java is resulting in negative value
(4 answers)
Closed 8 years ago.
final long COOKIE_TIMEOUT = 1000 * 60 * 60 * 24 * 30;
Output: -1702967296
Someone told me to put L after 1000 & it works
final long COOKIE_TIMEOUT = 1000L * 60 * 60 * 24 * 30;
Output: 2592000000
Why does that happen?
Integer overflow, put 1000L, this will force long conversion
UPDATE
Slightly longer explanation:
If you just do 1000*10 for example, java will see them as integers.
In your original code, you were doing an integer calculation which overflowed, then cast the overflowed value to long.
However if you put L after the first number, java will see them as longs (left-most operand defines the granularity) and you won't get an overflow.
As another example take this code:
double a = 5 / 2;
double b = 5d / 2;
System.out.println(a + " != " + b);
This will print out:
2.0 != 2.5
Why? When calculating a, java sees 5 and 2 as integers and does an integer division, then casts the result to a double. When calculating b you tell java that 5 is actually a double at which point it performs a double division.
Although COOKIE_TIMEOUT is long the right-hand expression consists of integers, so its type is int. The result is greater than Integer.MAX_VALUE that causes overflow. When at least one operand in your expression belongs to higher type (e.g. long) whole expression becomes long and overflow does not happen.
This is what you did in your second example when you added L modifier after one of the numeric constants. This constant became long, so the expression became long too.
This behavior is due to the type of the expression selected by the Java compiler. In this case it looks something like so:
int * int -> int (which overflows here during the multiplication)
long * long -> long
long * int = long * long (by promotion) -> long
int * long = long (by promotion) * long -> long
This promotion happens pretty much universally for the math operators: the widest/largest type is used, with the smaller type being promoted and the x op x -> x expression being applied (classically, integer vs. floating division).
The L results in a long value and thus the multiplication selected is long * long (by promotion) -> long, which is free from the immediate overflow discovered. The long expression result type propagates to all the other multiplications.
Bonus points: it would still fail (overflow) if written as 1000 * 60 * 60 * 24 * 30 * 1L, why?
It is greatter than Integer.MAX_VALUE which is 2147483647
By default all numeric litaral are considered as Integer. to define a Long numeric value you have to add L or 'l' with the number.
The reason of that behavior is integer overflow.
Your first statement can be understand like this:
long time = 1000 * 60 * 60 * 24 * 30;
is the same as
int time = 1000 * 60 * 60 * 24 * 30;
long timel = time;
First you compute the expression, then you assign to long type;
When you put suffix L to literal you define it as long type.
JSL 3.10.1. Integer Literals
An integer literal is of type long if it is suffixed with an ASCII
letter L or l (ell); otherwise it is of type int (ยง4.2.1).
long time = 1000L * ( 60 * 60 * 24 * 30);
can be written also as
long time = ((long) 1000) * ( 60 * 60 * 24 * 30);
More about Primitive Data Types
It is causing for Integer overflow(Max value upto 2147483647).
You can postfix L at the end of the any numeric value.
Like 1000L
Then it forcely converts into Long type
What happens here is that the right hand side is evaluated before the assignment to the left hand side. Since you are multiplying several ints, the resulting type will be int. Then, after evaluating the right hand side, it will see that it is supposed to assign this value to a long, and do the casting automatically.
So you have:
Evaluated right hand side as int: 1000 * 60 * 60 * 24 * 30 = 2,592,000,000.
The maximum value of an int is: 2,147,483,647.
So you have an overflow, which makes the int negative. This is then assigned to a long, still negative.
When you specify one of the operands on the right hand side to be long, then the expression will be evaluated has a long, which has a much larger maximum value.
Every number in the formula is an Integer, hence Java will perform all calculations in Integer and store the result temporarily as Integer. However the result exceeds Integer Max range (overflow), so it becomes negative.
1000 * 60 * 60 * 24 * 30 = 2592000000 (exceeds Integer.MAX_VALUE)
Only when Java needs to assign it to the Long variable Java will cast it into a Long. Since the result is already wrong result (due to overflow) then the Long variable will be assigned with the wrong result.
However if you already declare the 1000 as Long (1000L), then the remaining calculations will be done as Long instead of Integer.

strange behaviour of the java

hello I have some question about java, why the following code return strange value?
System.out.println("Strange " + (20 * 232792560)/20);
why do I recieve 18044195?
Because (20 * 232792560) overflows the range of an int, and wraps round the number range several times to become 360883904. That is then divided by 20 to give you the result that you see.
If you want the correct result, then you need to do:
System.out.println("Strange " + (20 * 232792560L) / 20);
(Marking a literal with an L means that the constant maths will be done with long, rather than with int, so this will no longer overflow.)
Because (20 * 232792560) will perform integer based multiplication and the result is obviously out of int's range, hence the value will be truncated.
Because 20 * 232792560 does not fit in 4 bytes (integer value).
So you got:
20 * 232792560 = 360883904; // because of int overflow
360883904 / 20 = 18044195;

Categories

Resources