Domanda

I am working with Local Binary Patterns (LBP) which produce numbers in the range 0-255. That means that they can fit in a byte (256 different values may be included into a byte). So that explains why many (if not all) implementation in java I have found uses byte[] to store these values.

The problem is that since I am interested in the rank of these values when converted to byte (from int for example) they do not keep the previous rank they had (as int for example) since byte are signed (as all but chars in java I think) and so the greater 128 values (127 and after) of the range 0-255 becomes negative numbers. Furthermore I think they are inverted in order (the negative ones).

Some examples to be more specific:

(int) 0 = (byte) 0
(int) 20 = (byte) 20
(int) 40 = (byte) 40
(int) 60 = (byte) 60
(int) 80 = (byte) 80
(int) 100 = (byte) 100
(int) 120 = (byte) 120
(int) 140 = (byte) -116
(int) 160 = (byte) -96
(int) 180 = (byte) -76
(int) 200 = (byte) -56
(int) 220 = (byte) -36
(int) 240 = (byte) -16

My question is whether there is a specific way to maintain the order of int values when converted to byte (meaning 240 > 60 should hold true in byte also -16 < 60!) while keeping memory needs minimum (meaning use only 8bits if that many are required). I know I could consider comparing the byte in a more complex way (for example every negative > positive and if both bytes are negative inverse the order) but I think it's not that satisfactory.

Is there any other way to convert to byte besides (byte) i?

È stato utile?

Soluzione

You could subtract 128 from the value:

byte x = (byte) (value - 128);

That would be order-preserving, and reversible later by simply adding 128 again. Be careful to make sure you do add 128 later on though... It's as simple as:

int value = x + 128;

So for example, if you wanted to convert between an int[] and byte[] in a reversible way:

public byte[] toByteArray(int[] values) {
    byte[] ret = new byte[values.length];
    for (int i = 0; i < values.length; i++) {
        ret[i] = (byte) (values[i] - 128);
    }
    return ret;
}

public int[] toIntArray(int[] values) {
    int[] ret = new byte[values.length];
    for (int i = 0; i < values.length; i++) {
        ret[i] = values[i] + 128;
    }
    return ret;
}

If you wanted to keep the original values though, the byte comparison wouldn't need to be particularly complex:

int unsigned1 = byte1 & 0xff;
int unsigned2 = byte2 & 0xff;
// Now just compare unsigned1 and unsigned2...
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top