17
class Main {  
   public static void main (String[] args){  
     long value = 1024 * 1024 * 1024 * 80;  
     System.out.println(Long.MAX_VALUE);  
     System.out.println(value);  
  }  
}

Output is:

9223372036854775807
0

It's correct if long value = 1024 * 1024 * 1024 * 80L;!

Jonhnny Weslley
  • 1,080
  • 2
  • 13
  • 24

5 Answers5

44

In Java, all math is done in the largest data type required to handle all of the current values. So, if you have int * int, it will always do the math as an integer, but int * long is done as a long.

In this case, the 1024*1024*1024*80 is done as an Int, which overflows int.

The "L" of course forces one of the operands to be an Int-64 (long), therefore all the math is done storing the values as a Long, thus no overflow occurs.

Erich
  • 3,946
  • 1
  • 22
  • 21
  • 4
    Arithmetic on, say, `short`s isn't done as `short`s, it's done as `int`s. – Tom Hawtin - tackline Sep 29 '09 at 20:57
  • Tom- That is very interesting, I'd never known that. I just tested it with two shorts (in C#, but similar action), and it DID do the math as an Integer... It must be just using an Int as the default value for plain numeric types. – Erich Sep 29 '09 at 21:02
  • i.e. short x = 0; short y = 0; x = x + y; would give a type mismatch error. – urmalp Sep 29 '09 at 21:06
  • Prateek- It doesn't though, the compiler is smart enough to make the differentiation. – Erich Sep 29 '09 at 21:24
  • Prattek: There's a bit of target typing going on there. You can also do `myShort += anotherShort;` but not `myShort = myShort + anotherShort;`. I like aribtrary precision integers... – Tom Hawtin - tackline Sep 29 '09 at 22:07
  • Erich: Integer arithmetic without `long` is done as `int`. Floating point arithmetic without `double` is done as `float` (I think I forget what happens you do `long+float`). I still like arbitrary precision arithmetic. – Tom Hawtin - tackline Sep 29 '09 at 22:10
  • That actually sounds familiar, and is a pretty reliable rule, it makes sense that would be the way it happens. long+float is done as a double I think, which is why you can do 5/3.0 and have it work. – Erich Sep 29 '09 at 22:35
  • your explanation is invalid. If your number is long you need to add L at the end of a number of size long. Valid -> 31536000000L*2 . Invalid -> 31536000000*2; [as L not added]. – surbhi bakshi Nov 23 '19 at 20:05
  • Moreover, 1000*60*60*24*365L this gives a different result then 1000*60*60*24*365*1L. As multiplication starts from L to R, 1000*60*60*24 -> gives integer number, and when you multiply it with 365L it give long as result. But when you multiply it with 365 -> output is greater than 32 bits [36 bits] and compiler removes all extra 4 bits and makes it 32 bits again and then multiplies it with 1L resulting in invalid result. – surbhi bakshi Nov 23 '19 at 20:09
  • Some reference would be handy. For example https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html (but I do not get which part does happen in this case) – Lubo Mar 29 '23 at 07:54
6

The integer literals are ints. The ints overflow. Use the L suffix.

long value = 1024L * 1024L * 1024L * 80L;

If the data came from variables either cast or assign to longs beforehand.

long value = (long)a * (long)b;

long aL = a;
long bL = b;
long value = aL*bL

Strictly speaking you can get away with less suffices, but it's probably better to be clear.

Also not the lowercase l as a suffix can be confused as a 1.

Brad Cupit
  • 6,530
  • 8
  • 55
  • 60
Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305
1

I suspect it's because by default java treats literals as integers, not longs. So, without the L on 80 the multiplication overflows.

developmentalinsanity
  • 6,109
  • 2
  • 22
  • 18
1

This code:

long value = 1024 * 1024 * 1024 * 80; 

multiplies some integers together, converts it to a long and then assigns the result to a variable. The actual multiplication will be done by javac rather than when it runs.

Since int is 32 bits, the value is wrapped and results in a zero.

As you say, using long values in the right hand side will give a result which only wraps if it exceeds 64 bits.

Pete Kirkham
  • 48,893
  • 5
  • 92
  • 171
1

If I understood it correctly, per your requirement, you wanted to multiply these values 1024 * 1024 * 1024 * 80;

In calculator I see values coming 1024 * 1024 * 1024 * 80=85899345920.

Here you go your java code: These are monetary value calculation in java

import java.math.BigDecimal;
public class Demo {
    public static void main(String[] args) {
        BigDecimal bd1 = new BigDecimal("1024");
        BigDecimal bd2 = new BigDecimal("1024");
        BigDecimal bd3 = new BigDecimal("1024");
        BigDecimal bd4 = new BigDecimal("80");
        BigDecimal bd5 = bd1.multiply(bd2).multiply(bd3).multiply(bd4);
        System.out.println(bd5); // output comes: 85899345920
    }
}
PAA
  • 1
  • 46
  • 174
  • 282