find endianness of system in java
Asked Answered
M

6

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.

Myeloid answered 24/2, 2012 at 13:26 Comment(13)
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.Machzor
I think you're out of luck. The JVM shields you from such implementation specific details.Dania
Nitpick: doesn't this use of union trigger undefined behavior? I'd use a char const * into a uint32_t instead.Stamey
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 purposeMyeloid
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.Jetliner
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?Myeloid
Only if the array is one word long!Jetliner
I got to know that jvm is big endian.But how can i prove find it using java code for the purpose of interviewMyeloid
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?Myeloid
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.Machzor
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?Myeloid
Also, a duplicate of: #982049Haircloth
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.Chrysoberyl
I
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");
}
Irvingirwin answered 24/2, 2012 at 13:35 Comment(8)
I cant use such libs its a interview question.Myeloid
@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?Irvingirwin
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?Machzor
any thing.Once cannot use even array.sort for interviews with big techi conmpaniesMyeloid
@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.Irvingirwin
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.Grijalva
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.Thermic
How about: System.out.println(ByteOrder.nativeOrder()); :)Grappa
G
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. ;)

Grijalva answered 24/2, 2012 at 16:9 Comment(7)
Best answer so far dude, pointing out reasons why you shouldn't do this.Kotto
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.Grijalva
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.Toilet
@PeterClark if you need to do this, use the built in libraries designed for that purpose ie Integer/Long reverseBytes docs.oracle.com/javase/8/docs/api/java/lang/…Grijalva
@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).Toilet
@PeterClark you can check ByteBuffer.nativeOrder()Grijalva
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 modeChipper
H
2
System.out.println(ByteOrder.nativeOrder());
Hifi answered 11/11, 2016 at 23:33 Comment(1)
duplicate answerDilatant
S
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);
    }
}
Saeger answered 4/4, 2014 at 5:43 Comment(0)
R
-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

Robin answered 8/5, 2013 at 4:54 Comment(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.Heaven
endianness works with memory representation, not values. Try your code and it'll always return little endianDiarist
H
-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.

Haircloth answered 24/2, 2012 at 13:34 Comment(13)
Agreed.But its a interview questionMyeloid
@user93796: So what? Does that magically invalidate how the JVM works?Haircloth
It doesnot.I have to come up with a algo to detect if jvm is big or little.NO MAGICMyeloid
@user93796: It always has the same endianness. Your algorithm should just always return 'Big', or however you wish to encode that information.Haircloth
Agreed.Still its a interivew question dudeMyeloid
@user93796: So, what do you want?Haircloth
let us continue this discussion in chatMyeloid
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.Grappa
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.Toilet
@PeterClark Really? If so then it doesn't conform to the JVM specs at the time this answer was written.Haircloth
@Haircloth 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.Toilet
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.Toilet
Running OpenJDK on macos on Intel's Xeon. JVM is little-endian. Have to convert int data in order write it to big-endian ICC profile file.Blossom

© 2022 - 2024 — McMap. All rights reserved.