Note that there are some explanatory texts on larger screens.

plurals
  1. POInconsistent behaviour of primitive integer types in Java
    primarykey
    data
    text
    <p>Can someone explain to me like I'm five why I get different behaviour for two of four primitive types representing integers in Java? AFAIK all four are signed and they all use the most significant bit as a sign bit, so why do byte and short behave normally, and int and long act, well, strange? The fragment of oracle docs explaining this would be perfect.</p> <pre><code>byte a = (byte) (Math.pow(2, 7)-1); //127 - as expected short b = (short) (Math.pow(2, 15)-1); //32767 - as expected int c = (int) (Math.pow(2, 31)-1); //2147483647 - as expected long d = (long) (Math.pow(2, 63)-1); //9223372036854775807 - as expected a = (byte) (Math.pow(2, 7)); //-128 - as expected b = (short) (Math.pow(2, 15)); //-32768 - as expected c = (int) (Math.pow(2, 31)); //2147483647 - why not '-2147483648'? d = (long) (Math.pow(2, 63)); //9223372036854775807 - why not '-9223372036854775808'? a = (byte) (Math.pow(2, 8)); //0 - as expected b = (short) (Math.pow(2, 16)); //0 - as expected c = (int) (Math.pow(2, 32)); //2147483647 - why not '0'? d = (long) (Math.pow(2, 64)); //9223372036854775807 - why not '0'? </code></pre> <p>I'm using Oracle's Java SE 1.7 for Windows. OS is Windows 7 Professional SP1</p> <pre><code>java version "1.7.0_45" Java(TM) SE Runtime Environment (build 1.7.0_45-b18) Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode) </code></pre> <hr> <p><strong>EDIT, after reading all the answers and tuning my code.</strong><br/> So, to sum up, the only way I found to get expected values is the use of BigInteger. Shift operator works well for bytes, shorts and ints, but when it comes to longs, I cought it on one malfunction.</p> <pre><code>byte a = (byte) ((1l &lt;&lt; 7) - 1); //127 - as expected short b = (short) ((1l &lt;&lt; 15) - 1); //32767 - as expected int c = (int) (1l &lt;&lt; 31) - 1; //2147483647 - as expected long d = (1l &lt;&lt; 63) - 1; //9223372036854775807 - as expected a = (byte) (1l &lt;&lt; 7); //-128 - as expected b = (short) (1l &lt;&lt; 15); //-32768 - as expected c = (int) 1l &lt;&lt; 31; //-2147483648 - as expected d = 1l &lt;&lt; 63; //-9223372036854775808 - as expected a = (byte) (1l &lt;&lt; 8); //0 - as expected b = (short) (1l &lt;&lt; 16); //0 - as expected c = (int) (1l &lt;&lt; 32); //0 - as expected d = 1l &lt;&lt; 64; //1 instead of 0, probably because of the word length limitation </code></pre> <p>With BigInteger everything works flawlessly</p> <pre><code>byte a = (byte) (new BigInteger("2").pow(7).longValue() - 1); //127 - as expected short b = (short) (new BigInteger("2").pow(15).longValue() - 1); //32767 - as expected int c = (int) (new BigInteger("2").pow(31).longValue() - 1); //2147483647 - as expected long d = (new BigInteger("2").pow(63).longValue() - 1); //9223372036854775807 - as expected a = (byte) (new BigInteger("2").pow(7).longValue()); //-128 - as expected b = (short) (new BigInteger("2").pow(15).longValue()); //-32768 - as expected c = (int) new BigInteger("2").pow(31).longValue(); //-2147483648 - as expected d = new BigInteger("2").pow(63).longValue(); //-9223372036854775808 - as expected a = (byte) (new BigInteger("2").pow(8).longValue()); //0 - as expected b = (short) (new BigInteger("2").pow(16).longValue()); //0 - as expected c = (int) (new BigInteger("2").pow(32).longValue()); //0 - as expected d = new BigInteger("2").pow(64).longValue(); //0 - as expected </code></pre> <p><strong>Thanks everyone for big help!</strong></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload