最大的Java Short(32767)加1没有变为负数?

时间:2017-03-08 21:50:00

标签: java binary short twos-complement

最近我了解了在基础二系统中表示正整数和负整数的两种恭维方法。然后我尝试使用带有以下短代码的java来实现这一点:

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

哪个输出:

  

a:2147483647

     

a + 1:-2147483648

     

b:32767

     

b + 1:32768

这让我感到困惑,因为我认为b + 1,以二进制表示为011111111111111,将变为1000000000000000或十进制,-32768。发生了什么事?

5 个答案:

答案 0 :(得分:11)

虽然b是短的,但表达式(b + 1)是一个int。右操作数是int,左操作数被提升为int,表达式是操作数的提升类型。

来自Java语言规范,5.6.2. Binary Numeric Promotion

  

应用扩展基元转换(第5.1.2节)来转换以下规则指定的一个或两个操作数:

     
      
  • 如果任一操作数的类型为double,则另一个操作数将转换为double。
  •   
  • 否则,如果任一操作数的类型为float,则另一个操作数转换为float。
  •   
  • 否则,如果任一操作数的类型为long,则另一个操作数将转换为long。
  •   
  • 否则,两个操作数都将转换为int。
  •   

请注意,即使两个操作数都是短类型,也会发生上一次促销。您无法使用(b + (short) 1)来避免升级为int。

来自15.18.2. Additive Operators (+ and -) for Numeric Types

  

数字操作数上的加法表达式的类型是其操作数的提升类型。

答案 1 :(得分:3)

执行+会自动将short提升为int。这样做,你会看到溢出。

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

来自Java语言规范,5.6.2. Binary Numeric Promotion

  

扩展基元转换(第5.1.2节)用于转换或   两个操作数由以下规则指定:

     
      
  • 如果任一操作数的类型为double,则另一个操作数将转换为double。
  •   
  • 否则,如果任一操作数的类型为float,则转换另一个操作数   漂浮。
  •   
  • 否则,如果任一操作数的类型为long,则另一个操作数为   转换为长。
  •   
  • 否则,两个操作数都将转换为int
  •   

注意最后一条规则,所以基本上这意味着即使它们都是短路,它们也会被提升为int,这是无法避免的。

你可以:

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

答案仍然有效。

答案 2 :(得分:3)

1是一个int字面值。在您计算b+1时,您实际上将b提升为int,然后添加1,从而产生32768,这是完全合法的{{1}价值。如果再次将其转换为int,您会看到您期望的溢出(short):

-32768

答案 3 :(得分:2)

正如其他人所指出的那样,加法将操作数提升为int

请注意,+=运算符会自动将转换回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;会产生与b += 1相同的结果。

答案 4 :(得分:2)

不需要混淆,试试这个:

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

你得到了什么?对,你得到:

  

错误:不兼容的类型:从int到short的可能有损转换       短c = b + 1;

那么,你的生产线会发生什么? System.out.println("b+1: "+(b+1));

嗯,b+1对于short来说太大了,正如你说的那样,但是你在这里添加一个int,结果也是一个int。而32768是一个有效的int。

正如其他人已经指出的那样,如果你明确地将其强制转换为(short),你就能得到你所要求的。

另一方面,这对short c = b + 1;不起作用,因为声明的类型是短的,而实际的类型是int

short c = (short) (b + 1);解决了“问题”