6
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
deamon
  • 89,107
  • 111
  • 320
  • 448

5 Answers5

9

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
  • 2,947
  • 1
  • 25
  • 19
  • 1
    Edit the better answer to incorporate the elements you like of the second best answer, upvote both, and accept the better (and now complete, with your edit) answer. That's what I do in such a situation, anyways. – ArtOfWarfare Oct 09 '12 at 15:41
4

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
  • 342,105
  • 78
  • 482
  • 720
2

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
  • 13,877
  • 6
  • 48
  • 58
  • 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 Feb 17 '10 at 10:54
  • 2
    @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 Feb 17 '10 at 11:43
2

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
  • 698,415
  • 94
  • 811
  • 1,216
1

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
  • 3,851
  • 1
  • 22
  • 21