views:

149

answers:

5
short permissions = 0755;
short requested = 0700;
short result = permissions & requested; 

I get a compiler error:

error possible loss of precision
found   : int
required: short

If I'm not totally wrong the result of binary AND is as long as the longest operand. Why is the result an integer?

Would there be a performance hit, if I would cast to short?

(short) permissions & requested
+5  A: 

The short answer (hah!) is, binary numeric promotion.

  • If any of the operands is of a reference type, unboxing conversion (§5.1.8) is performed. Then:
  • If either operand 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.
David
I'd like to accept both answers in this case.
deamon
+1  A: 

If I'm not totally wrong the result of binary AND is as long as the longest operand. Why is the result an integer?

Because the Java Language Specification says that the result of non-long integer arithmetic is always an int. It was probably written that way in acknowledgment of the fact that 32 bit CPUs work like that internally anyway - they actually don't have a way to do arithmetic with shorts.

Would there be a performance hit, if I would cast to short?

For the reason given above: no - it will have to happen anyway.

Michael Borgwardt
And it's the same in C, except that the cast is not required.
starblue
+1  A: 

The operands to the & operator will be promoted to int, and therefore the result is int, which will have to be casted to short if you want to store it in result. I don't think it should be a performance penalty unless the compiler is bad at generating code.

From http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.22.1:

When both operands of an operator &, ^, or | are of a type that is convertible (§5.1.8) to a primitive integral type, binary numeric promotion is first performed on the operands (§5.6.2).

From http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#170983:

[...] Otherwise, both operands are converted to type int.

Hans W
+2  A: 

I just wanted to add that you can actually avoid the cast if you use the arithmetic assignment operators. It's not faster or slower, just something that might be nice to know.

short permissions = 0755;
short requested = 0700;
short result = permissions;
result &= requested;
x4u
Thank you. I didn't know that.
deamon
Ughh ... I wouldn't write that unless the code was performance critical, and I had irrefutable evidence that this "obfuscated" version was faster.
Stephen C
@Stephen C: It won't be any faster. It leads to almost the same byte code when compiled (the cast is there as well) and will execute exactly as fast as the cast version if `result` is a local variable. Although if you call this *obfuscated* already, you should never have to read any of my code or from somebody else who is into *Spartan Programming*.
x4u
+2  A: 

Actually, I suspect that you might take a performance hit. There are only Java bytecodes for bitwise operations on int and long values. So the short values in permission and requested variables need (in theory) to be sign-extended before the operation is performed.

(And besides, I think you will find that the native bit-wise instructions are only available in 32 and 64 bit. Or if there are 8 or 16 bit versions, they will take the same number of clocks as the 32 bit version. The CPU datapaths will be at least 32 bits wide, and for and/or/xor there is no way to make narrower types work faster.)

In addition, even though the three variables have type short, the JVM will allocate the same number of bytes to store them. This is a consequence of the way that the JVM is designed.

So if your aim in using short was to save space or time, it probably won't help. But the only way to be sure is to use a profiler to compare the short and int versions of your application ... or better still, just forget about it.

Stephen C