Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Big-endian vs. Little-endian

Status
Not open for further replies.

mcklsn

Programmer
Mar 16, 2003
40
0
0
US
The data that I am reading from a file written by another application on a different web site is wrong-endian for use in Java (I can never remember which endian is which). I can reverse the 4 bytes in an int successfully using the following code:


public static int SwapIntBytes(int i)
{
int byte0 = i & 0xff;
int byte1 = (i>>8) & 0xff;
int byte2 = (i>>16) & 0xff;
int byte3 = (i>>24) & 0xff;
// swap the byte order
return (byte0<<24) | (byte1<<16) | (byte2<<8) | byte3;
}

But when the 4 bytes are a float, I don't know how to make a similar routine that will return them as a right-endian float. I'm asking for help again. Thanks very much.
Mcklsn
 
Ah, right: I see what your problem is... You can't do bit operations on floats in Java.

[If someone knows different, please correct me on that]

I wouldn't exactly call this a Big-Endian vs. Little-Endian problem, though - but that's not going to help you much. I'd say it's more to do with the file format rather than the bit order - although I'm sure some mad purist will reply saying that's the same thing.

[Boy do I hate the terms Big-Endian and Little-Endian... It sounds so geeky!!]

Anyway... I see what's going on with your integers is that they've been put into the file byte-by-byte.... So, someone has copied the Least Significant Byte in, then the next and so on. So, when you came to read this out, you read a whole int at once and then needed to re-order the bytes in it.

[Personally, I think it'd be simpler for you to read the data in one byte at a time, and just repeatedly multiply the resultant integer by 256 before adding the next byte to it.]

But back to the floats... You'll have to check out what they look like in the specific file format. The next move would be to read in the bytes of the float, and do some standard maths calculations on a new float in Java...

Start off with something like
Code:
float floatValue= 0.0f;
... Then add and multiply it up using the Java maths functions with the relevant data read in from the file... The IEEE floating point specification is explained at [and many other places, I'm sure, but that's the 1[sup]st[/sup] one I found on Google for you]

It says that...

The bit pattern
b[sub]1[/sub]b[sub]2[/sub]b[sub]3[/sub]...b[sub]9[/sub]b[sub]10[/sub]b[sub]11[/sub]...b[sub]32[/sub] of a word in a 32-bit machine represents the real number


(-1)[sup]s[/sup] x 2[sup]e-127[/sup] x (1.f)[sub]2[/sub]


where
s = b[sub]1[/sub]
e = (b[sub]2[/sub]...b[sub]9[/sub])[sub]2[/sub]
and f = b[sub]10[/sub]b[sub]11[/sub]...b[sub]32[/sub]
[/i]

Just remember that the bit order for the float your reading in is most likely to be something like


b[sub]7[/sub]b[sub]6[/sub]b[sub]5[/sub]b[sub]4[/sub]b[sub]3[/sub]b[sub]2[/sub]b[sub]1[/sub]b[sub]0[/sub] b[sub]15[/sub]b[sub]14[/sub]b[sub]13[/sub]b[sub]12[/sub]b[sub]11[/sub]b[sub]10[/sub]b[sub]9[/sub]b[sub]8[/sub] b[sub]23[/sub]b[sub]22[/sub]b[sub]21[/sub]b[sub]20[/sub]b[sub]19[/sub]b[sub]18[/sub]b[sub]17[/sub]b[sub]16[/sub] b[sub]31[/sub]b[sub]30[/sub]b[sub]29[/sub]b[sub]28[/sub]b[sub]27[/sub]b[sub]26[/sub]b[sub]25[/sub]b[sub]24[/sub]


(from what you've told us about the int you read in)
 
Just noticed something: In that extra-long line of bits, I've used b[sub]0[/sub] as the least significant bit, but the formula I copied in uses b[sub]1[/sub] as the least significant bit.

[I always call bit zero 'bit zero']

Anyway... I hope that helps you,
Stephen

p.s. If it's a double it'll be 64-bits long - the formula is at the same link as above.
 
The easiest thing to do is read the data into a ByteBuffer (java.nio.ByteBuffer, as of J2SDK 1.4.0).

example:

int datasize = <lengthOfInputData>;
ByteBuffer bb = ByteBuffer.allocate(datasize);
bb.order(ByteOrder.LITTLE_ENDIAN);

then you use bb.putInt() or bb.put() to fill the ByteBuffer with your input data. Hope this helps.
 
Just noticed this: These are the functions I think you should be using...
Code:
public static float Float.intBitsToFloat(int bits)

public static double Double.longBitsToDouble(long bits)
(Which were both available since JDK 1.0)

The Float and Double objects provide the very functions that you need... Do all the messing about that you did with your int, then call
Code:
Float.intBitsToFloat(int bits)

So, do something like...

Code:
int fourBytesOfTheFloat;

/*
 *Read in the four Bytes of the
 *float from the file just like
 *you read the int in.
 */
...
Code:
// Now swap them round using your function again
fourBytesOfTheFloat= SwapIntBytes(fourBytesOfTheFloat);

// Now that they are in the correct order,
// you can convert them into a float

float myFloat = 0.0f;

myFloat = Float.intBitsToFloat(fourBytesOfTheFloat);

If you want to do the same for a double, then read it in like a long (64-bits), and use
Code:
double myDouble = 0.0f;

// Read in and swap bytes
...
Code:
// Convert bytes into double

myDouble = Double.longBitsToDouble(eightBytesOfTheDouble);

(where
Code:
eightBytesOfTheDouble
is a
Code:
long
)

Sorry that I'm only telling you this now... I was sure there must be a Java way to solve your problem, but I didn't have the API documentation at hand.

Hope that's what you were after,
Stephen

p.s. Thanks jkaa679 - nice one! (But I only had the 1.3 SDK until this morning) [glasses]

p.p.s. mcklsn, you can also convert from doubles and floats into the long or int bytes... Just check out the SDK documentation which you can download from ... You can also see the documentation online at , but that doesn't seem to contain the original classes such as Float, Double, String and so on... Whereas the downloaded version has the lot.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top