2

It seems that Java runtime is Big Endian, but I can't find a reference to this, only for the class file specification of JVMs.

I'm looking for a definitive place in the JLS (regardless of version) which specifies that:

int value = 4096; // 0b0001 0000 0000 0000 = 0x10 00
                  //               \   /           |                             
int lastByte = value & 0xFF; //      |             |
assert lastByte == 0; // ---------------------------

and not lastByte == 16 (0x10)

OR where it specifies that this is platform/JVM dependent.

TWiStErRob
  • 44,762
  • 26
  • 170
  • 254
  • Possible duplicate of: http://stackoverflow.com/questions/362384/are-integers-in-java-little-endian-or-big-endian – Software Engineer May 23 '14 at 15:22
  • What makes you think that endianness is defined in Java at all? – Hot Licks May 23 '14 at 15:25
  • Also, what could you do with this information? (I get that you are curious.) – Sotirios Delimanolis May 23 '14 at 15:27
  • @EngineerDollery Not duplicate (that's about networking), I'm looking for a definitive place where the Java primitive integers are defined to be one of them or defined to be not defined. @SotiriosDelimanolis I'm just curious, because I've seen a lot of different frameworks building on this (mostly has to do something with `Color.rgba()`-like methods). @HotLicks that's why I put the "OR" clause there. – TWiStErRob May 23 '14 at 15:37
  • possible duplicate of [Java's Virtual Machine's Endianness](http://stackoverflow.com/questions/981549/javas-virtual-machines-endianness) – Drunix May 23 '14 at 16:25
  • 3
    The Java language does not in any way specify or depend on endianness. And in any official interfaces that do expose endianness to the "outside world" the endianness of the data is well-specified and often specifiable. And doing "bit twiddling" has nothing to do with endianness. – Hot Licks May 23 '14 at 16:45
  • (If you must, look at the specs for JNI -- the C-language "native" interface stuff.) – Hot Licks May 23 '14 at 16:46
  • 3
    The example you give in no way depends on endianness, so you can't even detect endianness. – Boann May 23 '14 at 16:56

1 Answers1

4

This is not so much a matter of the language, but rather of the virtual machine - that's why it is defined in the Java Virtual Machine Specifiction, but not in the Java Language Specification.

In fact, the results of these bitwise computations are independent of the endianness. Assume Big-Endian:

int value = 4111;                //   0x0000100F
int lastByte = value & 0xFF;     // & 0x000000FF
                                 // = 0x0000000F

Or Little-Endian:

int value = 4111;                //   0xF0010000
int lastByte = value & 0xFF;     // & 0xFF000000
                                 // = 0xF0000000

In both cases, the result is the same (in either of both forms).


One could now argue about the fact that 0x0000000F stands for 15, which implies big-endianness. This is at least implicitly defined in the definition of the lexical structure, in JLS Section 3.10.1, Integer Literals:

The largest positive hexadecimal, octal, and binary literals of type int - each of which represents the decimal value 2147483647 (2^31-1) - are respectively:

  • 0x7fff_ffff,
  • 0177_7777_7777, and
  • 0b0111_1111_1111_1111_1111_1111_1111_1111

Apart from that, the endianness is mainly relevant for storage and communication, but these are not language aspects and facilitated with things like the ByteOrder class, or on an API-level, like in the DataOutputStream::writeInt method:

Writes an int to the underlying output stream as four bytes, high byte first.


The only part where the endianness could be considered to influence the semantics of the language are the shift operations. But even there, it's mainly a matter of the interpretation of the language. The JLS Section 15.19 about Shift Operators states:

The value of n << s is n left-shifted s bit positions; this is equivalent (even if overflow occurs) to multiplication by two to the power s.

The value of n >> s is n right-shifted s bit positions with sign-extension. The resulting value is [ n / 2s ]. For non-negative values of n, this is equivalent to truncating integer division, as computed by the integer division operator /, by two to the power s.

The specification here states that the existing bits are shifted "left", and at the same time, that "left" is "the more significant position" (However, one could also say that << means "shifting right" in a Little-Endian world...)

Community
  • 1
  • 1
Marco13
  • 53,703
  • 9
  • 80
  • 159
  • *One could now argue about the fact that 0x0000000F stands for 15, which implies big-endianness.* Then how would 123.456f be interpreted on a little-endian machine?? – Hot Licks May 23 '14 at 20:41
  • @HotLicks Well, I just wanted to anticipate this possible argument, regardless of the fact that it would only make sense for the hex literals anyhow. One *could* define a language where 0xF0000000 means 15, but that's just not the way it is in Java... – Marco13 May 23 '14 at 22:56
  • @Marco13 This was one of my suspicions which I couldn't phrase, thanks for putting it into words! One more clarification: isn't it true that if you run your code examples as complied C++ on different architectures it'll yield different results? – TWiStErRob May 24 '14 at 20:11
  • @HotLicks `f` in `123.456f` is the single-precision floating point specifier, in `0x...F` the `F` is a hexadecimal digit. – TWiStErRob May 24 '14 at 20:12
  • @TWiStErRob I'm rather sure that HotLicks knows what the `f` stands for ;-) It was probably just aiming at the fact that the lexical structure does not really say anything about the endianness of the underlying machine. Concerning the C++ question: I'm not entirely sure what you mean, but you may want to have a look at http://stackoverflow.com/questions/1041554/ or similar questions. – Marco13 May 24 '14 at 20:28
  • @Marco13 thanks, that question cleared it. So my view is now: endianness only matter when you're tearing a multibyte primitive value apart with pointer access (obviously doesn't apply to every-day Java) or serialization. I was missing a level of abstraction between physical representation and bitwise operations. – TWiStErRob May 24 '14 at 21:20