lex*_*ore 3 java integer division integer-division
在Java中,如果我们划分bytes,shorts或ints,我们总是得到一个int.如果其中一个操作数是long,我们就会得到long.
我的问题是 - 为什么byte或short除法不产生byte或short?为什么总是int?
显然我不是在寻找"因为JLS这么说"的答案,我在Java语言中询问这个设计决策的技术原理.
考虑以下代码示例:
byte byteA = 127;
byte byteB = -128;
short shortA = 32767;
short shortB = -32768;
int intA = 2147483647;
int intB = - -2147483648;
long longA = 9223372036854775807L;
long longB = -9223372036854775808L;
int byteAByteB = byteA/byteB;
int byteAShortB = byteA/shortB;
int byteAIntB = byteA/intB;
long byteALongB = byteA/longB;
int shortAByteB = shortA/byteB;
int shortAShortB = shortA/shortB;
int shortAIntB = shortA/intB;
long shortALongB = shortA/longB;
int intAByteB = intA/byteB;
int intAShortB = intA/shortB;
int intAIntB = intA/intB;
long intALongB = intA/longB;
long longAByteB = longA/byteB;
long longAShortB = longA/shortB;
long longAIntB = longA/intB;
long longALongB = longA/longB;
Run Code Online (Sandbox Code Playgroud)
byteA除以byteB一个字节,除以不能是什么呢?
那么为什么必须byteAByteB是一个int?为什么不能shortALongB有short?
为什么intALongB必须如此long,结果总是适合int,不是吗?
更新
正如@Eran指出的那样,(byte)-128/(byte)-1结果128不适合byte.但为什么不short呢?
更新2
接下来,正如@Eran指出的那样(再次),(int) -2147483648 / (int) -1也不适合,int但结果int却不是long.
byteA除以byteB不能只是一个字节,可以吗?
它可以不是字节:
byteA = -128;
byteB = -1;
int div = byteA/byteB; // == 128, not a byte
Run Code Online (Sandbox Code Playgroud)
主要原因是机器通常只具有针对其本机整数类型(和浮点数)的加法指令。这就是为什么对于许多语言来说,算术表达式中最少使用的类型是int(通常是在某种程度上对应于基本机器整数类型的类型)。
例如,i386 规范说:
ADD 对两个操作数(DEST 和 SRC)执行整数加法。加法的结果分配给第一个操作数 (DEST),并相应地设置标志。将立即数字节添加到字或双字操作数时,立即值将符号扩展为字或双字操作数的大小。
这意味着在内部任何字节值都会扩展为整数(或类似的值)。毕竟这是合理的,因为处理器是 32/64 位,然后以这些大小执行任何算术。如果可以以字节为单位进行算术,那么通常认为这没有用。
JVM 规范说(为了补充)你有:iadd, ladd, fadd, dadd. 这只是反映了底层机器通常这样做的事实。任何其他选择都是可能的,但可能会以性能下降为代价。