Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / First Aid / March 2008

Tip: Looking for answers? Try searching our database.

Long integer to bytes?

Thread view: 
nooneinparticular314159@yahoo.com - 04 Mar 2008 03:28 GMT
I have a value that is represented as a 32 bit unsigned integer.
Java, from what I understand, does not handle unsigned integers, but
can represent the same number as a Long.  I need to turn this Long
into a 4 byte array representing the value of the 32 bit integer
(which is really a long).  Every method I've found so far seems to
operate on single byte integers, not 4 byte integers (ie. longs).  How
can I get my value into a 4 byte array?

Thanks!
nooneinparticular314159@yahoo.com - 04 Mar 2008 03:32 GMT
To follow up on that, here is an example:

Long PieceIndexNumber;
byte PieceIndexBytes = PieceIndexNumber.byteValue();

Note that I can represent the byte value of PieceIndexNumber as a
byte.  Not four bytes.  Just one.  That doesn't make sense, since a
long requires 4 bytes.  What am I doing wrong here?

Thanks!
Eric Sosman - 04 Mar 2008 04:09 GMT
> To follow up on that, here is an example:
>
[quoted text clipped - 4 lines]
> byte.  Not four bytes.  Just one.  That doesn't make sense, since a
> long requires 4 bytes.  What am I doing wrong here?

    Throwing away information.  (Also, confusing four with eight.)
Try this and see what you get:

    Long l1 = new Long(1);
    byte b1 = l1.byteValue();
    Long l2 = new Long(258);
    byte b2 = l2.byteValue();
    Long l3 = new Long(65539);
    byte b3 = l3.byteValue();
    Long l4 = new Long(16777220);
    b4 = l4.byteValue();
    System.out.println(b1 + " " + b2 + " " + b3 + " " + b4);

Try to predict the output before you actually run the code.

Signature

Eric Sosman
esosman@ieee-dot-org.invalid

nooneinparticular314159@yahoo.com - 04 Mar 2008 04:20 GMT
>      Throwing away information.  (Also, confusing four with eight.)
> Try this and see what you get:
[quoted text clipped - 8 lines]
>         b4 = l4.byteValue();
>         System.out.println(b1 + " " + b2 + " " + b3 + " " + b4);

Ok. It looks like you are overflowing (slightly) various
representations of a number by 1,2,3 and 4 by placing information into
the bytes too large to fit into individual bytes.  But how can I
represent my number as bytes?  (An array of bytes would be fine, if I
knew how to get it into one.)

Thanks!
nooneinparticular314159@yahoo.com - 04 Mar 2008 08:39 GMT
On Mar 3, 8:20 pm, "nooneinparticular314...@yahoo.com"
<nooneinparticular314...@yahoo.com> wrote:
> >      Throwing away information.  (Also, confusing four with eight.)
> > Try this and see what you get:
[quoted text clipped - 8 lines]
> >         b4 = l4.byteValue();
> >         System.out.println(b1 + " " + b2 + " " + b3 + " " + b4);

Ok.  I sort of see what you mean here.  A long is 8 bytes.  A 32 bit
unsigned int is 4 bytes.  I've tried using an 8 byte bytebuffer, but
that represented a signed value and gave me negative numbers if I
tried to store the wrong number.  How can I store and extract a 32 bit
unsigned int?

Thanks!
Nik.Ivanov - 04 Mar 2008 09:08 GMT
May be you need something like:
      public byte[] pack(long value){
        long tmp = value;
        int size = 0;
        do{
            size ++;
            tmp <<= Byte.SIZE - 1;
        }while (tmp != 0);
        byte[] bytes = new byte[size];
        for ( int i = 0; i < bytes.length ; i++){
            tmp = value;
            for ( int j = 0 ;j < i ; j++){
                tmp >>= Byte.SIZE - 1;
            }
            bytes[i] = (byte)(tmp & Byte.MAX_VALUE);
        }
        return bytes;
    }
I belive that an unpack method is pretty clear, then you have packing;
Nik.Ivanov - 04 Mar 2008 09:16 GMT
>                 do{
>                         size ++;
>                         tmp <<= Byte.SIZE - 1;
>                 }while (tmp != 0);

Whoops, made a very simple mistake, it should be tmp >>= Byte.SIZE -
1, instead of tmp <<= Byte.SIZE - 1;
Roedy Green - 04 Mar 2008 12:08 GMT
On Mon, 3 Mar 2008 19:28:14 -0800 (PST),
"nooneinparticular314159@yahoo.com"
<nooneinparticular314159@yahoo.com> wrote, quoted or indirectly quoted
someone who said :

>I have a value that is represented as a 32 bit unsigned integer.
>Java, from what I understand, does not handle unsigned integers, but
[quoted text clipped - 3 lines]
>operate on single byte integers, not 4 byte integers (ie. longs).  How
>can I get my value into a 4 byte array?

see http://mindprod.com/jgloss/unsigned.html

long in java is 8 bytes, 64 bits.
int in java is 4 bytes, 32 bits.

See http://mindprod.com/jgloss/primitive.html
--

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
rossum - 04 Mar 2008 13:19 GMT
On Mon, 3 Mar 2008 19:28:14 -0800 (PST),
"nooneinparticular314159@yahoo.com"

>I have a value that is represented as a 32 bit unsigned integer.
>Java, from what I understand, does not handle unsigned integers, but
[quoted text clipped - 5 lines]
>
>Thanks!
I assume that you read in the initial value as a Java long rather than
a Java integer.

To convert a long to a byte array I use the java.nio library.  This
assumes that all values are big-endian; I do not know if this will be
a problem for you.

Code fragment:

 import java.nio.LongBuffer;
 import java.nio.ByteBuffer;

 private final static int BYTES_PER_LONG = Long.SIZE / Byte.SIZE;

 public byte[] longToBytes(long inLong) {
   byte[] bArray = new byte[BYTES_PER_LONG];
   ByteBuffer bBuffer = ByteBuffer.wrap(bArray);
   LongBuffer lBuffer = bBuffer.asLongBuffer();
   lBuffer.put(inLong);
   return bArray;
 }

This returns an 8-byte array, you just need the relevant four bytes of
it.

rossum
nooneinparticular314159@yahoo.com - 04 Mar 2008 17:39 GMT
Ok.  I think I almost have it - sort of.  Using the BigInteger class,
I can actually store the value I need, and I can also get the last
four bytes out of it.  The problem is that the protocol that I'm using
requires a 32 bit unsigned integer.  So I can create a 32 bit unsigned
int, say 4294967295 (2^32 -1), which takes four bytes to represent.  I
then stick an extra byte in front of it containing 0x00, and
BigInteger correctly stores 4294967295.  (If I don't do this, it
stores -1.)  The problem now is that I need to send this data over the
network to other hosts, which may not be doing the BigInteger trick,
and which absolutely expect a 32 bit number.  I can't put the leading
0 in front, and I clearly don't want to send them -1.  Is there a way
around this, or am I just trying to use numbers that are too big to
represent this way?

Thanks!
rossum - 04 Mar 2008 19:12 GMT
On Tue, 4 Mar 2008 09:39:39 -0800 (PST),
"nooneinparticular314159@yahoo.com"

>Ok.  I think I almost have it - sort of.  Using the BigInteger class,
>I can actually store the value I need, and I can also get the last
[quoted text clipped - 11 lines]
>
>Thanks!
A few points:

BigIntegers are slow, ints or longs will be faster if speed is a
problem for you.

How much control do you have over the protocol used to send to other
hosts?  BigInteger is serializable, as are Integer and Long - perhaps
using a serialized Integer, Long or BigInteger might be better for
your purposes.

Once you have the four byte array you could just send the four bytes
in series.  You would need to agree the endianness before making the
change.

You could sent the 32 bit signed integer and expect the receiving end
to convert -1 back to 4294967295.

I suspect you are going to have to talk to whoever is building the
other end and come to some agreement as to how you are going to work
this.

Basically you are trying to use numbers that are too big to represent
in 31 bits (the positive part of the integer range).  To use the full
32 bits someone is going to have to deal with negative numbers - your
4294967295 = -1 problem.  On the positive side, both of these have
exactly the same bit pattern representation so your problem is more
one of translation than a more fundamental difficulty.

For myself I would probably go for a serialized signed Integer, but I
do not know the full details of your problem.

rossum
nooneinparticular314159@yahoo.com - 05 Mar 2008 02:37 GMT
> On Tue, 4 Mar 2008 09:39:39 -0800 (PST),
> "nooneinparticular314...@yahoo.com"
[quoted text clipped - 48 lines]
>
> rossum

I'm attempting to implement a well defined protocol which has been
widely implemented.  I can't alter the protocol if I want to
interoperate with existing implementations.

What I have gotten working is the use of BigIntegers internally within
my program, but then I convert the last four bytes to a ByteArray,
which means that I can send them over the network to other hosts
running other implementations.
Nigel Wade - 05 Mar 2008 09:52 GMT
> I'm attempting to implement a well defined protocol which has been
> widely implemented.  I can't alter the protocol if I want to
[quoted text clipped - 4 lines]
> which means that I can send them over the network to other hosts
> running other implementations.

Just use a DataOutputStream.

The unsigned arithmetic can be performed using longs. When you are ready to
output the data you mask the low order 4 bytes into an int. Then write the int
directly to the network using DataOutputStream.writeInt(). Java I/O is all
network byte order (big endian) so there's no need to worry about byte
swapping.

The following code will write the unsigned value 0xfedcba01 to a file:

package tests;

import java.io.DataOutputStream;
import java.io.FileOutputStream;

public class IntOutput {
   public static void main(String[] args) {
       // create a 32bit, "unsigned" integer.
       long l = 0xfedcba01L;
       
       // mask off the 32bit low order bits into an int.
       int i = (int) l & 0xffffffff;
       System.out.println(l);
       System.out.println(i);
       
       try {
           // open a DataOutputStream, in this case to a file, but it could
           // just as easily be  network connection.
           FileOutputStream fos = new FileOutputStream("tmp.tmp");
           DataOutputStream dos = new DataOutputStream(fos);
           
           dos.writeInt(i);
           
           dos.close();
           fos.close();
       }
       catch(Exception e) {
           System.err.println(e);
       }
   }
}

When you run it the output is:
4275878401
-19088895

The contents of the output file, when viewed using od are:

$ od -t x4 tmp.tmp
0000000 fedcba01      HEX
$ od -D tmp.tmp
0000000 4275878401    Unsigned int
$ od -t d4 tmp.tmp
0000000 -0019088895   Signed int

Signature

Nigel Wade, System Administrator, Space Plasma Physics Group,
           University of Leicester, Leicester, LE1 7RH, UK
E-mail :    nmw@ion.le.ac.uk
Phone :     +44 (0)116 2523548, Fax : +44 (0)116 2523555



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.