2015-12-21 4 views
0

Я хотел бы использовать десятичные числа, представленные в массивах байтов (формат BCD), для выполнения математических приращений десятичных значений в виде массивов байтов.Двоичная кодированная десятичная математика во встроенной Java

Пример: Я хотел бы сделать 255 + 1 в математике, которая дает 256. Когда сделано в формате двоичного массива, значение 255 будет 00000000FF, а 1 - 0000000001 Значение в шестнадцатеричном представлении байтов. Ожидаемый результат будет 0000000100.

Мой следующий код пытается сделать приращение массива 5 байтов 255 по 1. Мои конечные результаты: 00000001FE, который последний байт 0xFE должен быть 0x00. Как исправить мой алгоритм для правильного выполнения приращения массива 5 байтов, используя только базовые двоичные операнды (среда Java встроена)?

private static byte[] clkCtrCurr = new byte[5]; 
    private static byte[] inc = {0x00, 0x00, 0x00, 0x00, 0x01}; 
    private static byte buff; 
    private static byte carry; 

    public static void binAdd() { 
     buff = (byte) (clkCtrCurr[4]^inc[4]); 
     carry = (byte) (clkCtrCurr[4] & inc[4]); 
     clkCtrCurr[4] = buff; 
     clkCtrCurr[3] ^= carry; 
     buff = (byte) (clkCtrCurr[3]^inc[3]); 
     carry = (byte) (clkCtrCurr[3] & inc[3]); 
     clkCtrCurr[3] = buff; 
     clkCtrCurr[2] ^= carry; 
     buff = (byte) (clkCtrCurr[2]^inc[2]); 
     carry = (byte) (clkCtrCurr[2] & inc[2]); 
     clkCtrCurr[2] = buff; 
     clkCtrCurr[1] ^= carry; 
     buff = (byte) (clkCtrCurr[1]^inc[1]); 
     carry = (byte) (clkCtrCurr[1] & inc[1]); 
     clkCtrCurr[1] = buff; 
     clkCtrCurr[0] ^= carry; 
     clkCtrCurr[0] ^= inc[0]; 
    } 
+0

Что имеется в виду под «базовыми двоичными операндами»? Почему мы не используем + в байтах, присваиваем целое число и не обрабатываем его? –

+0

Это встроенная Java-система (JavaCard), которая может поддерживать или не поддерживать Int. Большая его поддержка - короткая, которая составляет 2 байта, а какой-то счетчик, такой как HOTP, требует таких вещей, как десятичные десятичные разряды размером 8-8 байтов, которые обычно обрабатываются в системе как байты. – thotheolh

ответ

1

BCD format означает, что каждая десятичная цифра (0-9) хранится в 4 бита (или 8, если без упаковки), что означает, что число выглядит десятичной при печати в шестнадцатеричном формате.

Пример: Десятичное число 123 должно храниться в BCD как 0x0123 (десятичный номер 291).

Если распакован, это будет просто 3 байта: 0x01 0x02 0x03 или 0x010203 (десятичный номер 66051).

Итак, если вы хотели 5-байтовый упакованный тупоконечника число BCD, т.е. 10-значного числа десятичную, и вы хотите увеличить, вы можете сделать это:

private static void increment(byte[] bcd) { 
    for (int i = bcd.length - 1; i >= 0; i--) { 
     byte b = bcd[i]; 
     if ((b & 0x0F) < 0x09) { 
      bcd[i] = (byte)(b + 1); 
      return; 
     } 
     if ((b & 0xF0) < 0x90) { 
      bcd[i] = (byte)((b & 0xF0) + 0x10); 
      return; 
     } 
     bcd[i] = 0; 
    } 
} 

Test

private static void print(byte[] bcd) { 
    for (int i = 0; i < bcd.length; i++) { 
     if (i != 0) 
      System.out.print(' '); 
     System.out.printf("%02x", bcd[i]); 
    } 
    System.out.println(); 
} 
public static void main(String[] args) { 
    byte[] bcd1 = { 0x00, 0x00, 0x00, 0x01, 0x23 }; // decimal 123 
    for (int i = 0; i < 10; i++) { 
     increment(bcd1); 
     print(bcd1); 
    } 
    byte[] bcd2 = { (byte)0x99, (byte)0x99, (byte)0x99, (byte)0x99, (byte)0x95 }; // decimal 9_999_999_995 
    for (int i = 0; i < 10; i++) { 
     increment(bcd2); 
     print(bcd2); 
    } 
} 

Выход

00 00 00 01 24 
00 00 00 01 25 
00 00 00 01 26 
00 00 00 01 27 
00 00 00 01 28 
00 00 00 01 29 
00 00 00 01 30 
00 00 00 01 31 
00 00 00 01 32 
00 00 00 01 33 
99 99 99 99 96 
99 99 99 99 97 
99 99 99 99 98 
99 99 99 99 99 
00 00 00 00 00 
00 00 00 00 01 
00 00 00 00 02 
00 00 00 00 03 
00 00 00 00 04 
00 00 00 00 05 
1

Попробуйте это.

static byte add(byte x, byte y, byte[] result, byte index) { 
    byte c = 0; 
    while (y != 0) { 
     byte t = (byte)(x & y); 
     c |= t; 
     x = (byte)(x^y); 
     y = (byte)(t << 1); 
    } 
    result[index] = x; 
    return (byte)((c & 0x80) != 0 ? 1 : 0); 
} 

static byte add(byte a, byte b, byte c, byte[] result, byte index) { 
    byte carry = add(a, b, result, index); 
    if (c > 0) 
     carry |= add(result[index], c, result, index); 
    return carry; 
} 

public static void add(byte[] a, byte[] b) { 
    byte c = 0; 
    c = add(a[4], b[4], c, a, (byte)4); 
    c = add(a[3], b[3], c, a, (byte)3); 
    c = add(a[2], b[2], c, a, (byte)2); 
    c = add(a[1], b[1], c, a, (byte)1); 
    c = add(a[0], b[0], c, a, (byte)0); 
}