1

I need to convert a number to byte array and then back to number. The problem is that the byte array is of variable size, so I need to convert a number given his byte length, the methods that I came up with are those: (Java)

private static byte[] toArray(long value, int bytes) {
    byte[] res = new byte[bytes];

    final int max = bytes*8;
    for(int i = 1; i <= bytes; i++)
        res[i - 1] = (byte) (value >> (max - 8 * i));

    return res;
}

private static long toLong(byte[] value) {
    long res = 0;

    for (byte b : value)
        res = (res << 8) | (b & 0xff);

    return res;
}

Here I use a long because 8 is the max bytes we can use. This method works perfectly with positive numbers but I can't seem to make the decoding work with negatives.

EDIT: to test this I've tried with processing the value Integer.MIN_VALUE + 1 (-2147483647) and 4 bytes

1
  • Dunno if your issue is solved now but... See if my Answer helps you with handling large negative values. Commented Jan 13, 2017 at 16:26

2 Answers 2

1

After accepting this as working solution, the Asker made some further optimizations.
I have included their own
linked code below for reference :

private static long toLong(byte[] value) {
    ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
    final byte val = (byte) (value[0] < 0 ? 0xFF : 0);

    for(int i = value.length; i < Long.BYTES; i++)
        buffer.put(val);

    buffer.put(value);
    return buffer.getLong(0);
}

OLDER ANSWER

edit : Based on comments (understanding Question better)

To make your toLong function handle both negative & positive numbers try this:

private static long toLong(byte[] value) 
{
    long res = 0;
    int tempInt = 0;
    String tempStr = ""; //holds temp string Hex values

    tempStr = bytesToHex(value);

    if (value[0] < 0 ) 
    { 
        tempInt = value.length;
        for (int i=tempInt; i<8; i++) { tempStr = ("FF" + tempStr); }

        res = Long.parseUnsignedLong(tempStr, 16); 
    }
    else { res = Long.parseLong(tempStr, 16); }

    return res;

}

Below is related bytesToHex function (re-factored to work out-of-box with any byte[] input...)

public static String bytesToHex(byte[] bytes)
{ String tempStr = ""; tempStr = DatatypeConverter.printHexBinary(bytes); return tempStr; }


Sign up to request clarification or add additional context in comments.

7 Comments

This is not variable, I cannot say "put this number in 5 bytes" or "get my number from those 5 bytes"
You aren't supposed to put in just 5 bytes only. All languages / OS read as 1, 2, 4 or 8 bytes at once. If your number needs 5 bytes only then you're already in a situation where you actually must read as 8 bytes. Use bit-shifting to keep your 40 bits (5 bytes) at one side of Array and fill remaining 3 byte slots with zero bits.
I did already do something like it (see my question) but the problem is that I don't know how to deal with negative values
I made my tests using my methods and yout bytesToHex: byte[] toArr = toArray(Integer.MIN_VALUE + 1, 4); System.out.println(bytesToHex(toArr)); System.out.println(toLong(toArr)); Result: "80000001" and "2147483649", negativity lost :/
Thank you for the answer, I wrote a slightly optimized version of it (the string operations aren't really fast) here's the new version using java's ByteBuffer pastebin.com/JKy8s5A6
|
1

Take a look at Apache Common Conversion.intToByteArray util method.

JavaDoc:

Converts a int into an array of byte using the default (little endian, Lsb0) byte and bit ordering

4 Comments

Just tested it:
long v = Integer.MIN_VALUE + 1; byte[] res = new byte[4]; longToByteArray(v, 0, res, 0, 4); long out = byteArrayToLong(res, 0, 0L, 0, 4); System.out.println(out); negativity lost
@SnowyCoder if this answer works then mark it as solution using icon.
@VC.One This answer doesn't work, as written in the second comment it loses the number negativity

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.