Biggest Java Short (32767) plus 1 doesn't turn negative?

I recently learned about two complimentary methods for representing both positive and negative integers in a base system. Then I tried to see this in action using java with the following short code:
int a=2147483647; System.out.println("a: "+a); System.out.println("a+1: "+(a+1)); short b=32767; System.out.println("b: "+b); System.out.println("b+1: "+(b+1)); 

What outputs:

a: 2147483647

a + 1: -2147483648

b: 32767

b + 1: 32768

Which bothers me, because I think that b + 1, being represented in binary form as 011111111111111, will turn into 1000000000000000, or into a decimal number, -32768. What's happening?

+7
java binary twos-complement short
source share
5 answers

Although b is short, the expression (b + 1) is int. The correct operand is int, the left operand advances to int, and the expression is an advanced type of operands.

From the Java language specification, 5.6.2. Binary numeric promotion :

The primitive conversion extension (ยง5.1.2) is used to convert one or both operands, as specified in the following rules:

  • If one of the operands 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.

Please note that this last advance occurs even if both operands are of short type. You cannot avoid moving into int with (b + (short) 1) .

From 15.18.2. Additive operators (+ and -) for numeric types

The type of additive expression for numeric operands is an advanced type of its operands.

+11
source share

Doing + automatically advances short to int . Do this and you will see an overflow.

 System.out.println("b+1: "+(short)(b+1)); //-32768 

From the Java language specification, 5.6.2. Binary numeric promotion :

The primitive conversion extension (ยง5.1.2) is used to convert either or both operands, as specified in the following rules:

  • If one of the operands is of type double, the other is converted to double.
  • Otherwise, if either operand is of type float, the other is converted to stay afloat.
  • Otherwise, if either operand is of type long, the other is converted to long.
  • Otherwise, both operands are converted to type int .

Pay attention to the last rule, therefore, in essence, this means that even if they are both shorts, they will be promoted to int, this cannot be avoided.

You can:

 short b= 32767; short d= 12; System.out.println("b+1: "+ (d+b)); // 32779 

And the answer will still be valid.

+3
source share

1 is an int literal. When you calculate b+1 , you actually push b by int , and then add 1 , resulting in 32768 , which is a perfectly legitimate int value. If you reset it to short again, you will see the overflow you are expecting ( -32768 ):

 System.out.println("b+1: " + (short)(b + 1)); 
+3
source share

As others have noted, the addition pushes the operands to int .

Note that the += operator automatically returns casting for short :

 short b=32767; System.out.println(b + 1); // 32768, because of integer promotion. b += 1; // Equivalent to b = (short)(b + 1); System.out.println(b); // -32768 

b++; / ++b; will give the same result as b += 1 .

+2
source share

No confusion, try the following:

 short b = 32767; short c = b + 1; 

What are you getting? That's right, you get:

error: incompatible types: possible lossy conversion from int to short short c = b + 1;

So what is happening on your line? System.out.println("b+1: "+(b+1)); ?

Well, b+1 too big for short , as you said correctly, but here you add an int to it, making the result also int. And 32768 is a valid int.

As others have already pointed out, if you explicitly omitted it to (short) , you received what you requested.

On the other hand, this does not work for short c = b + 1; since the declared type is short here and the actual type is int .

short c = (short) (b + 1); solves the "problem"

+2
source share

All Articles