2012-03-15 16 views
1

長いキャストがキャストされていることはわかっていますが、これを行うより良い方法があります。32ビット整数が範囲外の量だけ移動した

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: '&0xFF'の代わりに'&0xFFL'を使うと、 'long'値が得られます。 –

答えて

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はビッグエンディアンの1バイトオーダーしか取らないので、新しいバイト[]を作成するのに役立ちます。 (例はリトルエンディアンです;) –

関連する問題