-1

I know that the byte and the short data types are not given 2's complement treatment in Java. What I mean by this statement of mine is demonstrated in the example below:

byte b1 = 0xFF;    //error, 255 is outside the range of byte
byte b2 = 0b1100;    //12 is stored, and not -4

Now, take the following example:

byte b3 = 0;
b3 += 0xFF;
System.out.println(b3);    //prints -1 on the console

Should the 2nd line in the above example have thrown an error, single 0xFF is 255 and is outside the byte range?

Also, what this unfair game with byte and short? I mean, why not interpret them using the 2's complement system, just like int and long?

Prashant Pandey
  • 4,332
  • 3
  • 26
  • 44

3 Answers3

4

They are 2's complement - no idea where you got that from (but it's wrong). This:

byte b1 = 0xFF;

does not work because it is indeed outside the range of a byte. This however:

byte b3 = 0;
b3 += 0xFF;

because += is done on a wider range of int, you assign it to byte, which takes the last 8 bits, which happen to be -1.

Eugene
  • 117,005
  • 15
  • 201
  • 306
  • May be I articulated it wrong. What is mean is that supposing int i = 0xFFFFFFFF. Shouldn't this throw an error as well, as it is outside the range on int? – Prashant Pandey Aug 15 '18 at 11:57
  • Yes, they can. But 32 ones = -1 in 2's complement, right? Hence, it does not throw an error. Why then interpret 8 ones (in case of byte) as 255 and not -1? – Prashant Pandey Aug 15 '18 at 12:04
  • 2
    @PrashantPandey because `0xFF` is a *constant* and there are no `byte` constants, for the compiler that *is* and `int` – Eugene Aug 15 '18 at 12:09
  • 1
    Oh, this is what the problem was. Thank you so much for your time, and excuse my naive questions. – Prashant Pandey Aug 15 '18 at 12:15
2

Rather than trying to work this out by attempting to draw logical inferences, you should read the Java Language Specification:

Point 1. byte and short are signed types.

"The values of the integral types are integers in the following ranges:

  • For byte, from -128 to 127, inclusive
  • For short, from -32768 to 32767, inclusive" Source JLS 4.2.1

Point 2. The signed integral types are 2's complement.

"The integral types are byte, short, int, and long, whose values are 8-bit, 16-bit, 32-bit and 64-bit signed two's-complement integers, respectively, and char, whose values are 16-bit unsigned integers representing UTF-16 code units (§3.1)." Source JLS 4.2

Point 3. You can't assign an int variable to a byte variable.

If the type of the right-hand operand is not assignment compatible with the type of the variable (§5.2), then a compile-time error occurs. Source JLS 15.26.1

Point 4. You can assign an int compile-time constant expression to a byte variable provided that the value of the expression is in the range of byte.

"In addition, if the expression is a constant expression (§15.28) of type byte, short, char, or int:

  • A narrowing primitive conversion may be used if the variable is of type byte, short, or char, and the value of the constant expression is representable in the type of the variable." Source JLS 5.2

Point 5. b3 += 0xFF is equivalent to b3 = (byte)(b3 + 0xFF)

Source JLS 15.26.2

Point 6. There are no byte or short literals.

Source JLS 3.10.1

Community
  • 1
  • 1
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Actually, I just read that there are no byte and short literals in Java (the JVM doesn't know about byte and short). That's what the problem was. – Prashant Pandey Aug 15 '18 at 12:29
  • Incorrect. The JVM does know about `byte` and `short`. It is more complicated than you think. – Stephen C Aug 15 '18 at 12:50
  • Oh, is it so? I got that from https://stackoverflow.com/a/317861/6714426. Further, is there something somewhere I could read regarding this? – Prashant Pandey Aug 15 '18 at 13:05
  • Reference [JVM spec 2.3.1](https://docs.oracle.com/javase/specs/jvms/se10/html/jvms-2.html#jvms-2.3.1). The complication is that there are no opcodes for doing arithmetic, bitwise or comparison on `byte` / `short` / `char`. But there ARE opcodes that convert to and from those types. For example, `i2b`, `baload`. – Stephen C Aug 15 '18 at 13:06
  • I have commented on https://stackoverflow.com/a/317861/6714426. It is not accurate. – Stephen C Aug 15 '18 at 13:32
1

if you want to convert -minus values java 8 comes with utility methods to support unsigned operations

byte b1 = (byte) 0xFF;
Byte.toUnsignedInt(b1); // this method will return 255
Mohamed Fouad
  • 111
  • 1
  • 2
  • 10