2012-05-29 16 views
7

Baytları imzalı/imzasız int veya kısa olarak dönüştürmem gerekir.2 veya 4 bayttan imzalı/imzasız kısa/int'ye dönüştürme

Aşağıdaki yöntemler doğru mu? Hangi imzalı ve hangisi imzasız?

Bayt düzeni: LITTLE_ENDIAN

public static int convertTwoBytesToInt1(byte b1, byte b2) { 
    return (int) ((b2 << 8) | (b1 & 0xFF)); 
} 

VS.

public static int convertTwoBytesToInt2(byte b1, byte b2) { 
    return (int) (((b2 & 0xFF) << 8) | (b1 & 0xFF)); 
} 

ve

public static int convertFourBytesToInt1(byte b1, byte b2, byte b3, byte b4){ 
    return (int) ((b4<<24)+(b3<<16)+(b2<<8)+b1); 
} 

VS.

public static int convertFourBytesToInt2(byte b1, byte b2, byte b3, byte b4){ 
    return (int) (((b4 & 0xFF) << 24) | ((b3 & 0xFF) << 16) | ((b2 & 0xFF) << 8) | (b1 & 0xFF)); 
} 

Bu dönüşüm formlarda sadece ilgileniyorum. Teşekkürler!

+1

Fark yaratmıyor? Hala imzalanmış mı? –

cevap

6

Her çiftin ilk yöntemi (convertXXXToInt1()) imzalandı, ikincisi (convertXXXToInt2()) imzasız. b4 en yüksek bit ayarlanırsa, convertFourBytesToInt2() sonucu bu "imzasız" sürüm olması gerekiyordu rağmen negatif olacaktır böylece

Ancak, Java int her zaman imzalanır.

byte değerini varsayalım, b2 değeri onaltılık olarak 0xFF veya 0xFF'dir. << operatörü, -1 veya 0xFFFFFFFF değeriyle int türüne "yükseltilebilir" olmasına neden olur. 8 bitten sonra 0xFFFFFF00 olacak ve 24 baytlık bir kaymadan sonra 0xFF000000 olacaktır. Ancak, & bit kodlayıcısını uygularsanız, üst düzey bitler sıfıra ayarlanır. Bu işaret bilgilerini atar. İşte iki durumun ilk adımları, daha ayrıntılı olarak çalıştım.

olma:

byte b2 = -1; // 0xFF 
int i2 = b2; // 0xFFFFFFFF 
int n = i2 << 8; // 0x0xFFFFFF00 

İmzasız: bir int uymuyor çünkü

byte b2 = -1; // 0xFF 
int i2 = b2 & 0xFF; // 0x000000FF 
int n = i2 << 8; // 0x0000FF00 
+0

& 0xff yok set Yani yapabilirsiniz – blackwolf

+0

@blackwolf Aslında, bir fark yaratacak çünkü baytları + işleçle birleştiriyorsunuz. Bunu daha önce fark etmedim, çünkü diğerleri, bit manipülasyonu için tercih edilen '|' operatörünü kullanıyor. İfade, (int) olmalıdır ((b4 << 24) | ((b3 & 0xFF) << 16) | ((b2 & 0xFF) << 8) | (b1 & 0xFF)) – erickson

1

, 4 bayt işaretsiz dönüşümle birlikte bir sorun vardır. Aşağıdaki rutinler düzgün çalışıyor.

public class IntegerConversion 
{ 
    public static int convertTwoBytesToInt1 (byte b1, byte b2)  // signed 
    { 
    return (b2 << 8) | (b1 & 0xFF); 
    } 

    public static int convertFourBytesToInt1 (byte b1, byte b2, byte b3, byte b4) 
    { 
    return (b4 << 24) | (b3 & 0xFF) << 16 | (b2 & 0xFF) << 8 | (b1 & 0xFF); 
    } 

    public static int convertTwoBytesToInt2 (byte b1, byte b2)  // unsigned 
    { 
    return (b2 & 0xFF) << 8 | (b1 & 0xFF); 
    } 

    public static long convertFourBytesToInt2 (byte b1, byte b2, byte b3, byte b4) 
    { 
    return (long) (b4 & 0xFF) << 24 | (b3 & 0xFF) << 16 | (b2 & 0xFF) << 8 | (b1 & 0xFF); 
    } 

    public static void main (String[] args) 
    { 
    byte b1 = (byte) 0xFF; 
    byte b2 = (byte) 0xFF; 
    byte b3 = (byte) 0xFF; 
    byte b4 = (byte) 0xFF; 

    System.out.printf ("%,14d%n", convertTwoBytesToInt1 (b1, b2)); 
    System.out.printf ("%,14d%n", convertTwoBytesToInt2 (b1, b2)); 

    System.out.printf ("%,14d%n", convertFourBytesToInt1 (b1, b2, b3, b4)); 
    System.out.printf ("%,14d%n", convertFourBytesToInt2 (b1, b2, b3, b4)); 
    } 
} 
ben çok daha verimli olabilir bu şekilde ByteBuffer kullanmak ve koymazsan sen sadece ... `örnekler: .Sipariþ (ByteOrder.LITTLE_ENDIAN)` convertFourBytesToInt1 b1 At
+0

b1 nedir & 0xFF için? – ScottF

+0

@ScottF - Negatif değerleri önlemek için. – dmolony

İlgili konular