4

I have to use ints in java card but since the card itself does not support integers I use byte[] instead.

To represent numbers in hexadecimal format I check the first bit, if it is 1 - negative, if it is 0 - positive (binary wise). So if the leading bit is smaller than 8 it is positive, otherwise negative (hex wise).

Highest number: 7FFFFFFF

Lowest number: 80000000

Now I am wondering if I want to compare a value eg. 00000001 if it is to high/low, do I check without the most significant bit (FFFFFFF > 0000001 > 0000000) and check the most significant bit seperately (if > 7 => negative, else => positive) or is there a "smoother" way to do it?

Zong
  • 6,160
  • 5
  • 32
  • 46
achiever
  • 309
  • 1
  • 16
  • I assume you mean you want to compare *two* values? If so, the canonical way is to subtract them and see what the resulting sign is. – Hot Licks Dec 12 '13 at 16:31
  • well I want to know if a number is in between the boundaries and is positive or negative – achiever Dec 12 '13 at 16:36
  • What boundaries? If a signed number is 32 bits it's between 7FFFFFFF and 80000000 -- nothing to check. – Hot Licks Dec 12 '13 at 16:40
  • but how does the number knows if it is signed in a byte array? I guess that has to be done manually or am I overcomplicating things? – achiever Dec 12 '13 at 16:44
  • You need to DEFINE whether the number is signed or not. How do you know that an `int` is signed in C? Because you defined it `int` and not `unsigned int`. – Hot Licks Dec 12 '13 at 16:45
  • sure I usually define if it should be unsigned, but I am using a byte[] representation of an 32 bit signed integer and thus the comparison of two byte[] values: 80000000 < 00000000 will not be true even the first represents a negative number – achiever Dec 12 '13 at 16:56
  • 2
    http://stackoverflow.com/questions/13947638/simulate-int-variables-with-byte-or-short – UmNyobe Dec 12 '13 at 17:04
  • 1
    @UmNyobe Darn. maybe I'll host it somewhere the X-mas 2013 :P Should work though. – Maarten Bodewes Dec 12 '13 at 17:46
  • Hexadecimals is the encoding of binary data into two hexadecimal characters 0..F per byte. It's a string representation of the binary data. You don't want to compare hexadecimals, you want to compare two byte arrays (binary data) that contain a signed, big endian, two-complement number each. – Maarten Bodewes Dec 15 '13 at 21:39

1 Answers1

2

Sometimes you may not want to have the overhead of comparing using JCInteger given in this answer of mine. If you just want to compare two signed, two complement, big endian numbers (the default Java integer encoding) in a byte array, then you can use the following code:

/**
 * Compares two signed, big endian integers stored in a byte array at a specific offset.
 * @param n1 the buffer containing the first number
 * @param n1Offset the offset of the first number in the buffer
 * @param n2 the buffer containing the second number
 * @param n2Offset the offset in the buffer of the second number
 * @return -1 if the first number is lower, 0 if the numbers are equal or 1 if the first number is greater
 */
public final static byte compareSignedInteger(
        final byte[] n1, final short n1Offset,
        final byte[] n2, final short n2Offset) {

    // compare the highest order byte (as signed)
    if (n1[n1Offset] < n2[n2Offset]) {
        return -1;
    } else if (n1[n1Offset] > n2[n2Offset]) {
        return +1;
    }

    // compare the next bytes (as unsigned values)
    short n1Byte, n2Byte;
    for (short i = 1; i < 4; i++) {
        n1Byte = (short) (n1[(short) (n1Offset + i)] & 0xFF);
        n2Byte = (short) (n2[(short) (n2Offset + i)] & 0xFF);

        if (n1Byte < n2Byte) {
            return -1;
        } else if (n1Byte > n2Byte) {
            return +1;
        }
    }
    return 0;
}

Note that this code is not optimized, it may be faster to unroll the loop, and it should be possible to do this with just byte arithmetic.

Community
  • 1
  • 1
Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263