12

I'm trying to understand why this multiplication results in an incorrect value:

long max = (60 * 24 * 60 * 60 * 1000);

This should = 5,184,000,000

But in my Java program it = 889,032,704

Any idea why this is the case?

Kyle Anderson
  • 6,801
  • 1
  • 29
  • 41

2 Answers2

17

All of the values you're multiplying are ints so the result is an int which is cast to a long after overflow has already happened. Make one of the factors a long so that they are multiplied using 64b instructions

Try

long max = (60L * 24L * 60L * 60L * 1000L);

The L suffix specifies that the constant is a long value, not an int constant.

The language specification says

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).

and the section on multiplication says

The type of a multiplicative expression is the promoted type of its operands.

and type promotion of two ints leaves them as ints:

Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:

  • If either operand is of type double, the other is converted to double.
  • Otherwise, if either operand is of type float, the other is converted to float.
  • Otherwise, if either operand is of type long, the other is converted to long.
  • Otherwise, both operands are converted to type int
Community
  • 1
  • 1
Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
  • Thanks Mike. Your explanation makes perfect sense. – Kyle Anderson Apr 25 '14 at 17:11
  • 1
    @punkrocker27ka, This is a common error. So common that the [Go folk](http://golang.org/ref/spec#Constants) decided to make integer constants arbitrary precision: "Numeric constants represent values of arbitrary precision and do not overflow. ... These requirements apply both to literal constants and to the result of evaluating constant expressions." – Mike Samuel Apr 25 '14 at 17:15
  • Great :), This work like charm, Great Explanation :) – sameerali May 15 '17 at 23:53
5

This is due to integer overflow. Your right-side product is represented as int (default type of all operands) and it obliviously can't hold your "long" value.

Just make the first factor of your product long, either as long constant 60L, as in Mike's answer, or cast it explicitly (long) 60 :

long max = (long) 60 * 24 * 60 * 60 * 1000;

and you will get what you expect.

kiruwka
  • 9,250
  • 4
  • 30
  • 41