In Java, if we divide byte
s, short
s or int
s, we always get an int
. If one of the operands is long
, we'll get long
.
My question is - why does byte
or short
division not result in byte
or short
? Why always int
?
Apparently I'm not looking for the "because JLS says so" answer, I am asking about the technical rationale for this design decision in the Java language.
Consider this code sample:
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;
byteA
divided by byteB
can't be anything but a byte, can it?
So why must byteAByteB
be an int
? Why can't shortALongB
be short
?
Why does intALongB
have to be long
, the result will always fit int
, will it not?
Update
As @Eran pointed out, (byte)-128/(byte)-1
results in 128
which does not fit a byte
. But why not short
then?
Update 2
Next, as @Eran pointed out (again), (int) -2147483648 / (int) -1
also does not fit int
but the result is nevertheless int
, not long
.
The main reason is that machines usually have only add instructions for their native integer type (and floats). This is why for many languages the least used type in an arithmetic expression is int
(usually the type that correspond in some way to the basic machine integer type).
For example, i386 spec says:
ADD performs an integer addition of the two operands (DEST and SRC). The result of the addition is assigned to the first operand (DEST), and the flags are set accordingly. When an immediate byte is added to a word or doubleword operand, the immediate value is sign-extended to the size of the word or doubleword operand.
This means that internally any byte value is extended to an integer (or similar). After all this is reasonable as the processor is 32/64 bits and then perform any arithmetic in these sizes. If it could be possible to make arithmetic in bytes this is generally not considered as useful.
The JVM specs says that (for addition) you have : iadd
, ladd
, fadd
, dadd
. This just reflect the fact that underlying machines usually behave such. Any other choice could have been possible, probably at the price of performance degradation.