365連休

にわかのandroidとかの開発メモ。

【Self Stack Overflow】Javaで16進数文字列を正しく数値及び数値型へ変換する方法

自問

Javaで16進数文字列を正しい数値及び数値型へ変換する方法を教えてください。

以下のコードはエラーになります。

        Integer.parseInt("ffffffff", 16); //throws NumberFormatException
        Short.parseShort("ffff", 16); //throws NumberFormatException
        Byte.parseByte("ff", 16); //throws NumberFormatException

 

ベストアンサー

int型、short型、byte型の場合、一つ大きい型の数値クラスのparseXXXメソッドで正しい数値に変換することができる。

  • int val = (int)Long.parseLong("ffffffff", 16); //-1=0xffffffff
  • short val = (short)Integer.parseInt("ffff", 16); //-1=0xffff
  • byte val = (byte)Short.parseShort("ff", 16); //-1=0xff

 

long型の場合、より大きい整数型が無いためBigIntegerを使用して変換する。

  • BigInteger bigVal= new BigInteger("ffffffffffffffff", 16); //18446744073709551615
    long val = bigVal.longValue(); //-1=0xffffffffffffffff

 

それぞれダウンキャストを行わないと、C言語などで一般的なUnsigned数値を得ることもできる。 

 

各数値クラスのdecodeメソッドでも16進数を数値へ変換できるが、これは16進数と8進数 を解釈する。便利なようだが、それ自体が副作用とも云え、16進数を数値へ変換したいという用途においては、前述の方法を勧める。

 

検証コード

    public void test(){
        BigInteger unsignedLong = new BigInteger("ffffffffffffffff", 16); //unsigned = 18446744073709551615
        long longValue = unsignedLong.longValue(); //-1
        Log.d("unsignedVal = "+unsignedLong.toString()); //Log.dはSystem.out.printlnに読み替えてね
        Log.d(String.format("%d\t%x", longValue, longValue));

        long unsignedInt = Long.parseLong("ffffffff", 16); //long 0x00000000ffffffff = 4294967295
        int intValue = (int) unsignedInt; //int 0xffffffff = -1
        Log.d("unsignedVal = "+unsignedInt);
        Log.d(String.format("%d\t%x", intValue, intValue));

        int unsignedShort = Integer.parseInt("ffff", 16); //int 0x0000ffff = 65535
        short shortValue = (short) unsignedShort; //short 0xffff = -1
        Log.d("unsignedVal = "+unsignedShort);
        Log.d(String.format("%d\t%x", shortValue, shortValue));
        
        short unsignedByte = Short.parseShort("ff", 16); //short 0x00ff = 255
        byte byteValue = (byte) unsignedByte; //byte 0xff = -1
        Log.d("unsignedVal = "+unsignedByte);
        Log.d(String.format("%d\t%x", byteValue, byteValue));
    }

 

出力

15:25:30.167	unsignedVal = 18446744073709551615
15:25:30.168	-1	ffffffffffffffff
15:25:30.168 unsignedVal = 4294967295 15:25:30.168 -1 ffffffff
15:25:30.168 unsignedVal = 65535 15:25:30.169 -1 ffff
15:25:30.169 unsignedVal = 255 15:25:30.169 -1 ff

 

 

 

 

neet-rookie.hatenablog.com