5
public class Test {
        public static void main(String [] s) {
            int x = 99999;
            long y = 99999;

            long res = x * x;
            System.out.println("x^2 = " + res);
            res = y * y;
            System.out.println("y^2 = " + res);
        }
    }



 Output: 
    x^2 = 1409865409
    y^2 = 9999800001

I am really confused to see the output from the above code segment. I expected to get the same (correct) answer but here x^2 is actually wrong!

3 Answers3

8

99999 * 99999 = 1001010100000010001101011011000001 in binary (if you count these you will find out that you need 34 bits to represent this number in memory).

int is 32-bit long so two MSBs are cut out.

That gives you 01010100000010001101011011000001b = 1409865409 decimal as a result.

Assigning this value to 64-bit long doesn't change the result, multiplication of two integers gives you integer as a result.

zubergu
  • 3,646
  • 3
  • 25
  • 38
3

That is because you multiply integers x * x and the result of that will be integer (temporary variable, we talk here about the result of x * x operation, not res = part). Since the result will be bigger then Integer.MAX_VALUE, you will get some "strange" number. Then you place that number in the variable of long type.

This is how you fix this problem:

long res = 1l * x * x;

Now, it will calculate 1l * x, and since first number is long, it will calculate this as long, then multiply with x, and again, since first number is long, the result will be long, then this result will be placed in the variable res.

In similar way you fix problem with losing decimals, like for:

int a = 10;
int b = 3;
double d = a / b;

Result for this will be 3.0. But, if you do this:

double d = (1d *a) / b;
d = a / (b * 1d);
d = (double) a / d; 

Both will be 3.3333333333333335 (this 5, well thats another problem...). Also, casting to double for one of the variables works too (thanks @Aconcagua).

Adnan Isajbegovic
  • 2,227
  • 17
  • 27
  • 1
    Why multiplying with a constant - you simply can cast the first (or second...) operand to long or double respectively. – Aconcagua May 11 '16 at 08:32
  • that works to... dunno, got used to doing this, for no reason... – Adnan Isajbegovic May 11 '16 at 08:36
  • You are introducing a surplus operation (multiplication) this way. It should get optimized away, though, but you rely on optimization then while you had an alternative without having to rely on anything further... – Aconcagua May 11 '16 at 08:38
  • Not sure, if common sense, but furthermore, I personally consider casting as expressing the intention more explicitly/clearly. – Aconcagua May 11 '16 at 08:42
  • Well, what I do is I place 1d into static variable, so it gets more readable. But, yes, there is a cost of additional variable, but I guess casting and multiplication with 1 should be equally fast, by theory. Biggest question here is, what will JIT do in both case. – Adnan Isajbegovic May 11 '16 at 08:54
  • 1
    If a constant, the variable should not consume any memory... Both variants are equally fast, *if* the multiplication is optimized away, otherwise you get an additionally operation (on the FPU in case of double). The former, however, is what I would expect from any halfway feasible JIT, so in effect, you should be right... – Aconcagua May 11 '16 at 09:07
3

Because first x * x is done in int space and only then the result is put into a long. Therefore even though the long variable is large enough to hold the result, before putting the result into long it is first calculated as an int product and the result is truncated because it doesn't fit in int

ACV
  • 9,964
  • 5
  • 76
  • 81