0
byte b = 0b1111_1111;
byte c = 0b111_1111;
byte d = 0b0111_1111;

The first line causes a compilation error: incompatible types. I also tried 0xFF and decimal, the same. Thanks.

And I think byte means cannot be larger than what 8 bits hold. 0b1111_1111 is 8 bits.

Tiina
  • 4,285
  • 7
  • 44
  • 73
  • 9
    Because `0b1111_1111` is the number 255 which does not fit in a `byte`. Note that `byte` is a signed 8 bit number, with a range from -128 to +127. – Jesper Jun 15 '21 at 10:12
  • 1
    You should post the error-messsage. Also your description is wrong. The error is already in line 1 (variable b). You could also test this online: https://www.tutorialspoint.com/compile_java_online.php – TmTron Jun 15 '21 at 10:14
  • I think byte means cannot be larger than what 8 bits hold. 0b1111_1111 is 8 bits. – Tiina Jun 15 '21 at 10:16
  • @Jesper Then how do you give a byte variable -1 in binary format? – Tiina Jun 15 '21 at 10:19
  • `byte b = 0b1111_1111_1111_1111_1111_1111_1111_1111;` is how you write `-1` in binary. Keep in mind that this is an `int` (32 bit) literal. – Sweeper Jun 15 '21 at 10:20
  • @Tiina - The issue is really about the range of the Java `byte` type, not about the number of bits it holds. `0b1111_1111` is outside of that range ... but `0b1111_1111_1000_0000` is within the range!! – Stephen C Jun 15 '21 at 10:20
  • 1
    @Tiina Yes, a byte is 8 bit. But the syntax you are using does not allow you to define each bit separately. The syntax `0b1111_1111;` in java just means a number wrote in binary form. In the end `byte b = 0b1111_1111;` is literally exactly the same as `byte b = 255;`, only that you declare the number as binary. – OH GOD SPIDERS Jun 15 '21 at 10:20
  • @StephenC >_< Oh my! Very hard to believe that byte can hold so many bits even having my eyes seeing them! – Tiina Jun 15 '21 at 10:21
  • You are not listening. It is not about the number of bits. It is about the >>range<<. – Stephen C Jun 15 '21 at 10:22
  • 2
    Tiina I think the misunderstanding is about 0b. You think of it as the type you are assigning the value to (byte). But the compiler sees the literal and interprets it as an int. And thereafter it looks at the assignment. All you have to do is to tell the compiler your literal is a byte: `(byte) 0b1111_1111`. Or write -1 as binary int: `0b1111_1111_1111_1111_1111_1111_1111_1111` – Dietmar Höhmann Jun 15 '21 at 10:23
  • @DietmarHöhmann agree. I guess compilor first treats whatever not a long number into a int, and then convert whatever other integer like type from that. – Tiina Jun 15 '21 at 10:26

1 Answers1

2

All basic integer types in Java are signed. To be exact, byte, short, int and long are signed big endian two complement integers. That means that they run from - 2n-1 to 2n-1 - 1 where n is the number of bits - 8 for a byte (Byte.SIZE in Java), and therefore the range is from -128 to 127.

The number you are using is always an integer; number literals always are. However, the integer is actually the value 0x000000FF in hexadecimals. That cannot be stored as it is higher than 127. You can however do an explicit conversion; your value does consist of 8 bits after all.

byte b = (byte) 0b1111_1111

works because it simply disregards the 24 bits from the left hand side of the value. Now if you print it you will get -1 as value though as 0b1111_1111 represents 1 in 8 bit two complement form.

If you need it to represent the integer value 255 then you need to perform the following little trick:

int i = b & 0xFF;

which will actually do the following:

  • First it will convert b to the value 0xFFFFFFFF as integer using sign extension as all calculations default to integer, and it still thinks that b represents -1 after all.
  • Then it performs a bitwise AND with the value 0x000000FF (which is called a "mask"), resulting of course in the same value 0x000000FF which represents 255.

If you think this is a nuisance then you are right. Java should have used unsigned bytes, but it decided to use only one particular integer type that is signed. Maybe a bit overzealous but still a big improvement over e.g. C where you have way too many integer formats, and each of them may be represented differently on various machines.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • What exactly do you mean with 'big endian'? I'm quite sure all jvm implementations store integers in machine byte order, don't they? – Dietmar Höhmann Jun 15 '21 at 10:47
  • @DietmarHöhmann Yeah, but that would be the **virtual machine byte order** and that's big endian. That's at least how the VM is described, **how** the byte code gets interpreted is a different topic. If you describe a literal value then it uses the same order (although, funny enough, little endian machines use the same big endian description for integer values). All IO functions also default on Big Endian (`DataOutputStream`, `ByteBuffer` etc). – Maarten Bodewes Jun 15 '21 at 11:05
  • I see. So literals in a class file are always big endian and may (or may not) be translated to little endian by JIT compiler. Looking at the source of Java that makes sense. Thanks for the explanation! – Dietmar Höhmann Jun 15 '21 at 11:43