数値を符号なしバイトに変換する必要があります。数値は常に255以下であるため、1バイトに収まります。
また、そのバイトをその数値に戻す必要があります。 Javaでどうすればよいですか?私はいくつかの方法を試しましたが、どれも機能しません。これが私が今やろうとしていることです。
int size = 5;
// Convert size int to binary
String sizeStr = Integer.toString(size);
byte binaryByte = Byte.valueOf(sizeStr);
そして今、そのバイトを数値に戻すために:
Byte test = new Byte(binaryByte);
int msgSize = test.intValue();
明らかに、これは機能しません。何らかの理由で、常に数値を65
に変換します。助言がありますか?
バイトは常にJavaで署名されます。ただし、次のように0xFFでバイナリANDを実行すると、符号なしの値を取得できます。
int i = 234;
byte b = (byte) i;
System.out.println(b); // -22
int i2 = b & 0xFF;
System.out.println(i2); // 234
Java 8は、 Byte.toUnsignedInt
を提供して、byte
を符号なし変換によりint
に変換します。 OracleのJDKでは、これはreturn ((int) x) & 0xff;
として単純に実装されます。これは、HotSpotがこのパターンを最適化する方法を既に理解しているためですが、他のVMに組み込まれる可能性があります。さらに重要なことは、toUnsignedInt(foo)
の呼び出しが何をするかを理解するために事前の知識は必要ありません。
合計で、Java 8は、byte
とshort
を符号なしのint
とlong
に、およびint
を符号なしのlong
に変換するメソッドを提供します。 byte
を符号なしshort
に変換する方法は 意図的に省略 でした。これは、JVMがint
およびlong
の演算のみを提供するためです。
Intをバイトに戻すには、キャストを使用します:(byte)someInt
。結果の 縮小プリミティブ変換 は、最後の8ビットを除くすべてを破棄します。
予想される8ビット値を符号付きintから符号なし値に変換する必要がある場合、単純なビットシフトを使用できます。
int signed = -119; // 11111111 11111111 11111111 10001001
/**
* Use unsigned right shift operator to drop unset bits in positions 8-31
*/
int psuedoUnsigned = (signed << 24) >>> 24; // 00000000 00000000 00000000 10001001 -> 137 base 10
/**
* Convert back to signed by using the sign-extension properties of the right shift operator
*/
int backToSigned = (psuedoUnsigned << 24) >> 24; // back to original bit pattern
http://docs.Oracle.com/javase/tutorial/Java/nutsandbolts/op3.html
int
以外をベースタイプとして使用する場合は、明らかにシフト量を調整する必要があります。 http://docs.Oracle.com/javase/tutorial/Java/nutsandbolts/datatypes。 html
また、byte
型を使用できないことを忘れないでください。使用すると、他の回答者が述べたように、署名された値になります。 8ビットの符号なし値を表すために使用できる最小のプリミティブ型は、short
です。
Integer.toString(size)
呼び出しは、整数のchar表現、つまりchar '5'
に変換します。その文字の ASCII表現 は値65です。
最初に文字列を解析して整数値に戻す必要があります。 Integer.parseInt
を使用して、元のint値を取得します。
結論として、符号付き/符号なしの変換では、String
を画像から除外し、@ JBが示唆するようにビット操作を使用するのが最善です。
ソリューションは正常に機能します(ありがとう!)が、キャストを避けて低レベルの作業をJDKに任せたい場合は、DataOutputStreamを使用してintを書き込み、DataInputStreamを使用してそれらを読み戻すことができます。これらは自動的に符号なしとして扱われますバイト:
Intをバイナリバイトに変換します。
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
int val = 250;
dos.write(byteVal);
...
dos.flush();
それらを読み返す:
// important to use a (non-Unicode!) encoding like US_ASCII or ISO-8859-1,
// i.e., one that uses one byte per character
ByteArrayInputStream bis = new ByteArrayInputStream(
bos.toString("ISO-8859-1").getBytes("ISO-8859-1"));
DataInputStream dis = new DataInputStream(bis);
int byteVal = dis.readUnsignedByte();
特にバイナリデータ形式(フラットメッセージ形式など)の処理に役立ちます。
BigIntegerを使用したバイトと符号なし整数の処理:
byte[] b = ... // your integer in big-endian
BigInteger ui = new BigInteger(b) // let BigInteger do the work
int i = ui.intValue() // unsigned value assigned to i
char
を除き、Javaの他のすべての数値データ型は署名されます。
前の回答で述べたように、0xFF
でand
操作を実行すると、符号なしの値を取得できます。この回答では、それがどのように起こるかを説明します。
int i = 234;
byte b = (byte) i;
System.out.println(b); // -22
int i2 = b & 0xFF;
// This is like casting b to int and perform and operation with 0xFF
System.out.println(i2); // 234
マシンが32ビットの場合、int
データ型には値を保存するために32ビットが必要です。 byte
に必要なのは8ビットのみです。
int
変数i
は、メモリ内で次のように表されます(32ビット整数として)。
0{24}11101010
byte
変数b
は次のように表されます。
11101010
byte
sは符号なしなので、この値は-22
を表します。 (2の補数を検索して、メモリ内の負の整数を表す方法の詳細をご覧ください)
キャストがint
である場合、キャストは数値の符号を保持するため、-22
のままです。
1{24}11101010
キャストされた32-bit
のb
の値は、0xFF
でand
操作を実行します。
1{24}11101010 & 0{24}11111111
=0{24}11101010
次に、234
を答えとして取得します。
プリミティブラッパークラスを使用する場合、これは機能しますが、すべてのJavaタイプはデフォルトで署名されます。
public static void main(String[] args) {
Integer i=5;
Byte b = Byte.valueOf(i+""); //converts i to String and calls Byte.valueOf()
System.out.println(b);
System.out.println(Integer.valueOf(b));
}