2012-03-15 2 views
1

Я знаю, что есть недостающее количество, но есть лучший способ сделать это, что менее запутанно, чем показанный пример.32 бит int сдвинуто на величину, не находящуюся в диапазоне

static long getLong(byte[] sourceBytes, int sourceBytesIndex, int numOfBytesToConvert) 
{ 
    long longValue = 0; 

    longValue = (sourceBytes[sourceBytesIndex] & 0xFF) + 
         ((sourceBytes[sourceBytesIndex + 1] & 0xFF) << 8); 

    if (numOfBytesToConvert > 2) 
    { 
     longValue += ((sourceBytes[sourceBytesIndex + 2] & 0xFF) << 16) + 
           ((sourceBytes[sourceBytesIndex + 3] & 0xFF) << 24); 

     if (numOfBytesToConvert > 4) 
     { 
      longValue += ((sourceBytes[sourceBytesIndex + 4] & 0xFF) << 32) + 
            ((sourceBytes[sourceBytesIndex + 5] & 0xFF) << 40); 

      if (numOfBytesToConvert > 6) 
      { 
       longValue += ((sourceBytes[sourceBytesIndex + 6] & 0xFF) << 48) + 
             ((sourceBytes[sourceBytesIndex + 7] & 0xFF) << 56); 
      } 
     } 
    } 

    return longValue; 
} 
+1

Как насчет простого цикла? – Voo

+0

BTW: Использование '& 0xFFL' вместо' & 0xFF' даст вам «длинные» значения. –

ответ

4

Я предпочитаю использовать ByteBuffers, вы также можете использовать оператор switch.

static long getLong(ByteBuffer bb, int numOfBytesToConvert) { 
    switch (numOfBytesToConvert) { 
     case 8: 
      return bb.getLong(); 
     case 6: 
      long aChar = bb.getChar(); 
      long anInt = bb.getInt() & 0xFFFFFFFFL; 
      return bb.order() == ByteOrder.LITTLE_ENDIAN 
        ? aChar << 32 + anInt 
        : anInt << 16 + aChar; 
     case 4: 
      return bb.getInt() & 0xFFFFFFFFL; 
     case 2: 
      return bb.getChar(); 
     default: 
      throw new IllegalArgumentException(); 
    } 
} 

ByteBuffer обрабатывает как байтовый порядок байтов, а также положение и конец полезных байтов в буфере. (Использование limit())

Я предпочитаю прямой ByteBuffers, так как он может быть большим без использования большой кучи и быстрее, чем byte[] при использовании собственного байтового порядка.

+0

Thx, для информационного ответа и умного решения. – arge

1

Это делает трюк:

long value = new BigInteger(sourceBytes).longValue(); 

static long getLong(byte[] sourceBytes, int sourceBytesIndex, int numOfBytesToConvert) { 
    byte[] bytes = new byte[numOfBytesToConvert]; 
    System.arraycopy(sourceBytes, sourceBytesIndex, bytes, 0, numOfBytesToConvert); 
    return new BigInteger(sourceBytes).longValue(); 
} 
+0

Я подозреваю, что 'sourceBytesIndex' и' numOfBytesToConvert' важны. ;) –

+0

Помню, я когда-то слышал о функции System.arraycopy. Если он все еще существует (его довольно старый), то он может помочь;) –

+0

Наряду с созданием нового байта [] это может помочь, за исключением того, что BigInteger принимает только один байтовый порядок, большой endian, поэтому цикл может быть лучшим выбором. (; пример мало endian.;) –

Смежные вопросы