17

I found out that algorithm (int C) for checkink if machine is bigindian or littleindian is

int is_big_endian(void)
{
    union {
        uint32_t i;
        char c[4];
    } bint = {0x01020304};

    return bint.c[0] == 1; 
}

How can i find such thing in *java?*I dont want to use inbuilt libs as this is a interview question.I want to find it out in java.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
user93796
  • 18,749
  • 31
  • 94
  • 150
  • 6
    Java is strictly big endian as far as I know. There's no way (and indeed no reason) to find out the endianness of the underlying architecture without invoking native code. – biziclop Feb 24 '12 at 13:27
  • I think you're out of luck. The JVM shields you from such implementation specific details. – Landei Feb 24 '12 at 13:29
  • 2
    Nitpick: doesn't this use of `union` trigger undefined behavior? I'd use a `char const *` into a `uint32_t` instead. – Fred Foo Feb 24 '12 at 13:30
  • ok.agreed that java donot allow u to find endianess of machine.But how can i find out endianess of jvm itself using java code?This is just for interview purpose – user93796 Feb 24 '12 at 13:33
  • 1
    The only reason I can think of for wanting to know this is to create binary files for consumption by a non-Java application, or to build a compiler in Java, perhaps. Rather obscure. – DNA Feb 24 '12 at 13:34
  • also if i get a stream of bytes from a little endian machine and now i want to conver it to big indian .Will reversing the byter array will do the job? – user93796 Feb 24 '12 at 13:34
  • Only if the array is one word long! – DNA Feb 24 '12 at 13:35
  • I got to know that jvm is big endian.But how can i prove find it using java code for the purpose of interview – user93796 Feb 24 '12 at 13:36
  • assuming both macines has a wordlength of 1 byte. If my data is abcd, i will get it in form abcd from little machine and i have to store it as dcba.Am i correct? – user93796 Feb 24 '12 at 13:37
  • IF word length is 1 byte, there's no endianness at all. Your byte is your word. Complications only set in when you have multi-byte words, as you do in almost every system. – biziclop Feb 24 '12 at 13:46
  • but suppose i have data as abcd . When storint it in main memory little will store it as A at 100, B at101 ,c at 102,D at103 and big will store it as D at 100,C at 101,B at102,A at 103 .Am i correct? – user93796 Feb 24 '12 at 13:53
  • Also, a duplicate of: http://stackoverflow.com/questions/981549/javas-virtual-machines-endianness – Marcin Feb 24 '12 at 13:59
  • Specifying the Endianness is also desired when specifying the processor type on an OSGi bundle manifest instead of the generic 'arm' string. See OSGi Core spec. – D-Dᴙum Mar 20 '17 at 17:00

6 Answers6

45

I take no credit for this, however you can try:

import java.nio.ByteOrder;

if (ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN)) {
  System.out.println("Big-endian");
} else {
  System.out.println("Little-endian");
}
DNA
  • 42,007
  • 12
  • 107
  • 146
Nim
  • 33,299
  • 2
  • 62
  • 101
  • I cant use such libs its a interview question. – user93796 Feb 24 '12 at 13:39
  • 1
    @user93796, this is a "system" library, it's not a third-party library, and IMO, fair-game. This solves the problem in the most straightforward way - what do you need a kludge for? – Nim Feb 24 '12 at 13:42
  • 3
    It's not a lib, it's a built-in class. You wouldn't get far in Java without them. In fact you wouldn't get anywhere without them. If they don't like your answer, ask yourself this: do I really want for a company that asks such stupid questions? – biziclop Feb 24 '12 at 13:43
  • any thing.Once cannot use even array.sort for interviews with big techi conmpanies – user93796 Feb 24 '12 at 13:46
  • 3
    @user93796, says who? If someone set me a test, and the crux of the problem wasn't to implement a sorting algorithm, I would use an existing implementation. Any other approach is plain daft IMO. – Nim Feb 24 '12 at 13:54
  • 3
    Would you hire someone who wrote their own (and potentially buggy) sort() method instead of using the tested, well understood built in one, if it did the job. – Peter Lawrey Feb 24 '12 at 16:06
  • 2
    I strongly doubt there is any other way to do this, actually. Java is designed to be platform-independent, so almost all of its methods will give you the same results on a big-endian or little-endian machine. – Louis Wasserman Feb 24 '12 at 16:22
  • How about: System.out.println(ByteOrder.nativeOrder()); :) – Koray Tugay Jan 20 '16 at 18:47
4

How can i find such thing in *java?*I dont want to use inbuilt libs as this is a interview question.I want to find it out in java.

You can't do this in pure Java without calling a library. This is because;

  • Java says you shouldn't care about such things if you can avoid it.
  • Java is relatively feature poor as a language and relies on its libraries to do a lot of things which might be a language feature in another language.
  • Most people don't distinguish between what the language does and what is a built in library because the distinction is rarely useful.
  • Byte code/virtual machine is not big endian or little endian as such, only real implementations are. ;)

Older libraries only support big endian (which most processors use, Intel being a notable exception) Newer libraries can be set one way or the other.

It is pretty rare that you need to know how to re-write built in functionality again, and if you did, you would read the code on how it is done already (even if you did know how it could be done)

I have seen many people redevelop built in functionality which is buggy, more difficult to use because it behave in unexpected ways and less performant than the built in libraries. It is quite possible to write something faster or more bespoke than what is in the JDK, but its very rarely useful to know how off the top of your head.

I do get these questions from time to time, and before answering the question I point out all the reasons you wouldn't do this. ;)

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • Best answer so far dude, **pointing out reasons why you shouldn't do this**. – El Developer Feb 24 '12 at 16:25
  • You still need to show you could do it, even if you shouldn't. I would say, look at how its done already should be a reasonable answer. Recently I had to create a custom scapegoat TreeMap which used `int` as a key and multiple values for that key and recycled all its nodes. Of course I copied good portions of code from TreeMap and kept the names the same as much as possible. – Peter Lawrey Feb 24 '12 at 16:30
  • This question is not asking why you wouldn't want to do this, I very very explicitly need to do this. As I just discovered thanks to Nim's actual answer - the Java VM I'm debugging on Android is using LITTLE_ENDIAN while our native code runs in BIG_ENDIAN - thus I need to know this in order to know to properly convert between them when sending the bytes for a bitmap image from Java to CPP. – Peter Clark Dec 05 '17 at 23:08
  • @PeterClark if you need to do this, use the built in libraries designed for that purpose ie Integer/Long reverseBytes https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html#reverseBytes-long- – Peter Lawrey Dec 05 '17 at 23:48
  • @PeterLawrey Thanks for making me aware of those utility methods - I still need to know if the data needs reversing in the first place (thus still a need to determine endian-ness). – Peter Clark Dec 06 '17 at 00:02
  • @PeterClark you can check ByteBuffer.nativeOrder() – Peter Lawrey Dec 06 '17 at 00:10
  • ARM and AArch64 CPUs often run in little-endian mode, and IIRC some might not support a big-endian mode. Intel was one of the first to make little-endian CPUs but it has become more common as x86 became widely used. Even PowerPC and MIPS CPUs can support bi-endian, although IDK how common it is to run themin little-endian mode – Peter Cordes Apr 18 '20 at 20:39
3
System.out.println(ByteOrder.nativeOrder());
Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
Liju John
  • 1,749
  • 16
  • 19
1

On JVMs that have the sun.misc.Unsafe class and store an Unsafe singleton in a static instance variable named "theUnsafe", then the following approach can be used. I tested this successfully on the Oracle JVM and openjdk. The code works by writing a short (2 bytes) value of 1 to memory, and then reading the first byte.

import java.lang.reflect.Field;
import sun.misc.Unsafe;

public class Endianness {
    private static Unsafe getUnsafe() {
        Unsafe unsafe = null;
        try {
            Field f = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
            f.setAccessible(true);
            unsafe = (Unsafe) f.get(null);
        } catch (Exception e) {}
        return unsafe;
    }

    public static void main(String[] args) {
        Unsafe unsafe = getUnsafe();
        long address = unsafe.allocateMemory(2);
        short number = 1;
        unsafe.putShort(address, number);
        if (unsafe.getByte(address) == 0)
            System.out.println("Big Endian");
        else
            System.out.println("Little Endian");
        unsafe.freeMemory(address);
    }
}
dannyadam
  • 3,950
  • 2
  • 22
  • 19
-3
public static void getEndian(){
    int a = 0;
    // 0x0....01 
    int b = 1;
    //0x0..0,0.01,0..0,0..0
    int combine = (b<<16) | a;
    System.out.println(combine);
    if(combine == 65536){
        System.out.println("LittleEndian");
    }else{
        System.out.println("BigEndian");
    }
}

My approach is just to shift the number and compare whether it works as expectations for little endian mechanism

catspirit
  • 49
  • 5
  • 2
    As far as I can tell this should not work. Regardless of how the system stores in memory, Bitwise-OR will use the correct order of bits. 65536 | 0 will = 65536 in any system. – Boris Apr 26 '16 at 20:52
  • 1
    endianness works with memory representation, not values. Try your code and it'll always return little endian – phuclv Jul 29 '16 at 10:32
-6

The JVM, and therefore Java, is strictly big-endian, regardless of the host platform.

However, in relation character encodings, it is possible to extract information about the system default encoding, which may have an endianness (in fact, it is likely to).

Here's some code for you:

boolean is_big_endian()
{
    return true;
}

Edit:

See this answer with references: Java's Virtual Machine's Endianness

In fairness, it is possible to call into native code, and there you could get things that are native byte ordered.

Marcin
  • 48,559
  • 18
  • 128
  • 201
  • Agreed.But its a interview question – user93796 Feb 24 '12 at 13:35
  • 1
    @user93796: So what? Does that magically invalidate how the JVM works? – Marcin Feb 24 '12 at 13:40
  • It doesnot.I have to come up with a algo to detect if jvm is big or little.NO MAGIC – user93796 Feb 24 '12 at 13:42
  • @user93796: It always has the same endianness. Your algorithm should just always return 'Big', or however you wish to encode that information. – Marcin Feb 24 '12 at 13:45
  • Agreed.Still its a interivew question dude – user93796 Feb 24 '12 at 13:46
  • @user93796: So, what do you want? – Marcin Feb 24 '12 at 13:47
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/8178/discussion-between-user93796-and-marcin) – user93796 Feb 24 '12 at 13:55
  • This is one of the dumbest answers in Stackoverflow, also there is no "bool" type in Java, and Java methods are usually written in camelCase. – Koray Tugay Jan 20 '16 at 18:45
  • This is incorrect. The JVM I'm running on android is LITTLE ENDIAN. Please delete this answer, it's a lie. I got this info with Nim's answer. – Peter Clark Dec 05 '17 at 23:05
  • 1
    @PeterClark Really? If so then it doesn't conform to the JVM specs at the time this answer was written. – Marcin Dec 06 '17 at 01:08
  • 1
    @Marcin I followed the code a bit deeper and found that the code I'm using calls into native (c/c++) code (`bitmap.copyPixelsToBuffer`) in order to do the actual copying of memory. This might be the reason the buffer I'm getting back is little endian (it definitely is, it's an image with 1 byte per color channel and I'm getting BGRA instead of ARGB). I'm not 100% sure if the JVM itself uses little-endian, I might guess not if the JVM spec explicitly state that. The docs on ByteOrder.nativeOrder() mention that the constant exists because perf sensitive code can be run natively. – Peter Clark Dec 06 '17 at 02:17
  • Apologies for the use of "lie" in my comment - poor wording. Also feel free to keep this answer, though it might be worth adding a note that links to byte order and clarifies that at the very least some performance sensitive code can be run on the native hardware and thus use the native byte ordering. Thanks for double checking, I would have forgotten to leave the above details. – Peter Clark Dec 06 '17 at 02:19