为什么Java中短整数除法的结果类型不是一个短整数?

时间:2010-02-13 07:45:35

标签: java syntax

考虑以下代码:

public class ShortDivision {
    public static void main(String[] args) {
        short i = 2;
        short j = 1;
        short k = i/j;
    }
}

编译它会产生错误

ShortDivision.java:5: possible loss of precision
found   : int
required: short
        short k = i/j;

因为表达式i / j的类型显然是int,因此必须转换为short。

为什么i/j的类型不短?

3 个答案:

答案 0 :(得分:18)

来自Java spec

  

5.6.2二进制数字促销

     

当运算符将二进制数字提升应用于一对操作数时,每个操作数必须表示数值类型的值,以下规则按顺序应用,使用扩展转换(第5.1.2节)根据需要转换操作数:

     

如果任一操作数的类型为double,则另一个操作数转换为double。

     

否则,如果任一操作数的类型为float,则另一个操作数转换为float。

     

否则,如果任一操作数的类型为long,则另一个操作数转换为long。

     

否则,两个操作数都将转换为int类型。

对于二进制操作,小整数类型被提升为int,操作结果为int


编辑:为什么会这样?简短的回答是Java从C复制了这种行为。更长的答案可能与所有现代机器至少进行32位本机计算这一事实有关,而且某些机器实际上可能更难做8位和16位操作。

另请参阅:OR-ing bytes in C# gives int

答案 1 :(得分:2)

关于动机:让我们想象一下这种行为的替代方案,看看为什么它们不起作用:

备选方案1:结果应始终与输入相同。

添加int和short的结果应该是什么?

两个短裤相乘的结果应该是什么?结果通常适合int,但因为我们截断为short,所以大多数乘法都会无声地失败。之后施放到int将无济于事。

备选方案2:结果应始终是可以代表所有可能输出的最小类型。

如果返回类型很短,则答案并不总是可以表示为短。

空头可以持有-32,768到32,767的值。然后这个结果会导致溢出:

short result = -32768 / -1; // 32768: not a short

所以你的问题变成了:为什么添加两个整数不会返回多长?两个整数应该乘以什么?好久不过?一个BigNumber来覆盖整数最小值的情况?

备选方案3:选择大多数人可能最需要的东西

所以结果应该是:

  • int用于乘以两个short或任何int操作。
  • 短,如果加上或减去短路,将短路除以任何整数类型,乘以两个字节,......
  • 如果将一个字节向右移位,则为
  • 字节;如果向左移位,则为int。
  • 等...

如果没有基本逻辑,记住所有特殊情况都会很困难。简单地说:整数运算的结果总是一个int。

答案 2 :(得分:0)

它只是一种设计选择,与C / C ++保持一致,在设计Java时它们是主导语言。

例如,可以实现i * j,以便从byte =>提升类型。 short,short => int,和int =>很长,这样可以避免溢出,但事实并非如此。 (它在某些语言中有用)如果需要当前的行为,可以使用Casting,但是一些位的丢失将是明确的。

类似地,可以从byte / short =>提示i / j; float或int / long =>双