Long integer to bytes?

  • Follow


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!
0
Reply nooneinparticular314 3/4/2008 3:28:14 AM

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!
0
Reply nooneinparticular314 3/4/2008 3:32:04 AM


nooneinparticular314159@yahoo.com wrote:
> 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?

     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.

-- 
Eric Sosman
esosman@ieee-dot-org.invalid
0
Reply Eric 3/4/2008 4:09:34 AM

> =A0 =A0 =A0Throwing away information. =A0(Also, confusing four with eight.=
)
> Try this and see what you get:
>
> =A0 =A0 =A0 =A0 Long l1 =3D new Long(1);
> =A0 =A0 =A0 =A0 byte b1 =3D l1.byteValue();
> =A0 =A0 =A0 =A0 Long l2 =3D new Long(258);
> =A0 =A0 =A0 =A0 byte b2 =3D l2.byteValue();
> =A0 =A0 =A0 =A0 Long l3 =3D new Long(65539);
> =A0 =A0 =A0 =A0 byte b3 =3D l3.byteValue();
> =A0 =A0 =A0 =A0 Long l4 =3D new Long(16777220);
> =A0 =A0 =A0 =A0 b4 =3D l4.byteValue();
> =A0 =A0 =A0 =A0 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!
0
Reply nooneinparticular314 3/4/2008 4:20:18 AM

On Mar 3, 8:20=A0pm, "nooneinparticular314...@yahoo.com"
<nooneinparticular314...@yahoo.com> wrote:
> > =A0 =A0 =A0Throwing away information. =A0(Also, confusing four with eigh=
t.)
> > Try this and see what you get:
>
> > =A0 =A0 =A0 =A0 Long l1 =3D new Long(1);
> > =A0 =A0 =A0 =A0 byte b1 =3D l1.byteValue();
> > =A0 =A0 =A0 =A0 Long l2 =3D new Long(258);
> > =A0 =A0 =A0 =A0 byte b2 =3D l2.byteValue();
> > =A0 =A0 =A0 =A0 Long l3 =3D new Long(65539);
> > =A0 =A0 =A0 =A0 byte b3 =3D l3.byteValue();
> > =A0 =A0 =A0 =A0 Long l4 =3D new Long(16777220);
> > =A0 =A0 =A0 =A0 b4 =3D l4.byteValue();
> > =A0 =A0 =A0 =A0 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!

0
Reply nooneinparticular314 3/4/2008 8:39:14 AM

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;
0
Reply Nik 3/4/2008 9:08:19 AM

On Mar 4, 12:08 pm, "Nik.Ivanov" <Nik.Iva...@gmail.com> wrote:
>                 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;
0
Reply Nik 3/4/2008 9:16:08 AM

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
>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?

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
0
Reply Roedy 3/4/2008 12:08:16 PM

On Mon, 3 Mar 2008 19:28:14 -0800 (PST),
"nooneinparticular314159@yahoo.com"
<nooneinparticular314159@yahoo.com> wrote:

>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!
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

0
Reply rossum 3/4/2008 1:19:03 PM

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!
0
Reply nooneinparticular314 3/4/2008 5:39:39 PM

On Tue, 4 Mar 2008 09:39:39 -0800 (PST),
"nooneinparticular314159@yahoo.com"
<nooneinparticular314159@yahoo.com> wrote:

>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!
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

0
Reply rossum 3/4/2008 7:12:42 PM

On Mar 4, 11:12=A0am, rossum <rossu...@coldmail.com> wrote:
> On Tue, 4 Mar 2008 09:39:39 -0800 (PST),
> "nooneinparticular314...@yahoo.com"
>
>
>
> <nooneinparticular314...@yahoo.com> wrote:
> >Ok. =A0I think I almost have it - sort of. =A0Using the BigInteger class,=

> >I can actually store the value I need, and I can also get the last
> >four bytes out of it. =A0The problem is that the protocol that I'm using
> >requires a 32 bit unsigned integer. =A0So I can create a 32 bit unsigned
> >int, say 4294967295 (2^32 -1), which takes four bytes to represent. =A0I
> >then stick an extra byte in front of it containing 0x00, and
> >BigInteger correctly stores 4294967295. =A0(If I don't do this, it
> >stores -1.) =A0The 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. =A0I can't put the leading
> >0 in front, and I clearly don't want to send them -1. =A0Is there a way
> >around this, or am I just trying to use numbers that are too big to
> >represent this way?
>
> >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? =A0BigInteger 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. =A0You 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). =A0To use the full
> 32 bits someone is going to have to deal with negative numbers - your
> 4294967295 =3D -1 problem. =A0On 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

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.
0
Reply nooneinparticular314 3/5/2008 2:37:26 AM

nooneinparticular314159@yahoo.com wrote:


> 
> 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.

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

-- 
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
0
Reply Nigel 3/5/2008 9:52:19 AM

12 Replies
134 Views

(page loaded in 0.147 seconds)

Similiar Articles:


















7/25/2012 11:46:28 PM


Reply: