3

I tried to calculate the maximum value of int, however I can not figure out why calculated value that is cast to int is lower than when cast to long. I raised (2^31) - 1 on the calculator and the value is

2_147_483_647

and I would expect the same when I rise 2^31 and deduct 1 in Java, it should calculate maximum number for int 2147483647, but it doesn't.

System.out.println(((long) Math.pow(2, 31)) - 1); 
System.out.println((int) Math.pow(2, 31) - 1); 

The first calculation gives: 2_147_483_647

Second calculation gives: 2_147_483_646

Zabuzard
  • 25,064
  • 8
  • 58
  • 82
mat1
  • 83
  • 10

5 Answers5

5

A cast has precedence over subtraction. You should rather do the subtraction first:

 System.out.println((int) (Math.pow(2, 31) - 1)); 
  • Math.pow(2, 31) is 2_147_483_648 with a type of double (since Math.pow() returns a double) , this number does not fit into an int.

  • When you cast the double 2_147_483_648 to an int, it gets truncated to the largest value an int can hold (see How does double to int cast work in Java).

  • The cast truncates the double 2_147_483_648 to the int 2_147_483_647.

  • Then your code subtracts 1, and ends up with 2_147_483_646.
nos
  • 223,662
  • 58
  • 417
  • 506
2

First example

Let us analyze what you have done. The first example is

((long) Math.pow(2, 31)) - 1;

This means that you first compute Math.pow(2, 31) which yields

2.147_483_648 E9

After that you cast to long. Note that long has enough place for this value, so it represents it as

2_147_483_648

Then you subtract 1 and get

2_147_483_647

Second example

Let's now see what the second example does. Your wrote

(int) Math.pow(2, 31) - 1

This is interpreted as

((int) Math.pow(2, 31)) - 1

So the same as before but with a cast to int instead of long. Now note that int does not have enough place for the value. The biggest int that can be represented is

2_147_483_647 // MAX_INTEGER

and thus you will also get exactly this value here. After that you subtract 1 and get

2_147_483_646

Correction

I think you thought that

(int) Math.pow(2, 31) - 1

evaluates to

(int) (Math.pow(2, 31) - 1)

but it doesn't. If you make this explicit you will indeed get

2_147_483_647

as expected.


Operator precedence

You can read about that in the Java Language Specification, refer to JLS§15.15 Unary Operators. Casting has precedence over operators like subtraction.

That is because casting is an unary operator whereas subtraction is binary. Unary has precedence over binary. The official documentation therefore gives the following table as overview:

+----------------------------------------------------------------+
| Operators             | Precedence (top is high, bottom low)   |
|-----------------------|----------------------------------------|
| postfix               | expr++ expr--                          |
| unary                 | ++expr --expr +expr -expr ~ !          |
| multiplicative        | * / %                                  |
| additive              | + -                                    |
| shift                 | << >> >>>                              |
| relational            | < > <= >= instanceof                   |
| equality              | == !=                                  |
| bitwise AND           | &                                      |
| bitwise exclusive OR  | ^                                      |
| bitwise inclusive OR  | |                                      |
| logical AND           | &&                                     |
| logical OR            | ||                                     |
| ternary               | ? :                                    |
| assignment            | = += -= *= /= %= &= ^= |= <<= >>= >>>= |
+----------------------------------------------------------------+

Casting is of course part of the unary category.

Zabuzard
  • 25,064
  • 8
  • 58
  • 82
1

Typecast the whole Math.pow(2, 31) - 1). Like this

System.out.println((int) (Math.pow(2, 31) - 1));
वरुण
  • 1,237
  • 3
  • 18
  • 50
1

You put the brackets in the wrong place. It should be:

System.out.println((int) (Math.pow(2, 31) - 1));
Planck Constant
  • 1,406
  • 1
  • 17
  • 19
0

Writing your code like this (int) Math.pow(2, 31) - 1 makes Java cast Math.pow(2, 31) to int. Since that is more than the max value of int, it results to be 2_147_483_647. Since you subtract 1 afterwards, you get a value lower than the actual solution. You should rather cast the whole calculation to int than just Math.pow(2, 31) so it looks like this: (int) (Math.pow(2, 31) - 1)

Naeramarth
  • 112
  • 13