Javaには、符号なしバイトなどはありません。
低レベルのコードを使用する場合、128を超える符号なしの値を持つバイトを処理する必要がある場合があります。これにより、Javaは、MSBが符号に使用されているため、それらを負の数として解釈します。
これを回避するための良い方法は何ですか?(Javaを使用しないと言うことはオプションではありません)
このようにすれば実はif文と足し算をなくすことができます。
byte[] foobar = ..;
int value = (foobar[10] & 0xff);
この方法では、Java はバイトを負の数として解釈せず、整数の符号ビットも反転しません。
配列から単一の値を読み取るときは、それをshortやintなどにコピーし、負の数を正の値に手動で変換します。
byte[] foobar = ..;
int value = foobar[10];
if (value < 0) value += 256 // Patch up the 'falsely' negative value
配列に書き込むときにも同様の変換を行うことができます。
javaはとにかく内部的に32ビット値を使用するため(配列内でない限り、バイトに対しても)、intを使用する方が一般にshortを使用するよりも優れています。したがって、intを使用すると、バイトコード内のshort値との間の不要な変換を回避できます。
ビット操作/符号なしバイトを実行する最良の方法は、intを使用することです。符号付きであっても、符号なしバイトとして扱うための予備ビット(合計32)がたくさんあります。また、すべての数学演算子は、小さい固定精度の数値をintに変換します。例:
short a = 1s;
short b = 2s;
int c = a + b; // the result is up-converted
short small = (short)c; // must cast to get it back to short
このため、整数に固執し、それをマスクして、関心のあるビットを取得するのが最善です。例:
int a = 32;
int b = 128;
int foo = (a + b) | 255;
Javaプリミティブ型に関する詳細情報は次のとおりですhttp://mindprod.com/jgloss/primitive.html
最後の些細な注意点として、Javaには符号なしの固定精度の数値が1つあります。それがcharプリミティブです。
おそらくあなたの最善の策は、バイトではなく整数を使用することです。バイトを置き換えるために特別なオブジェクトを作成する必要がなく、128を超える数を許可する余地があります。
これは私より賢い人たち(みんな)からも提案されています
これは非常に遅い応答であることはわかっていますが、まったく同じことをしようとしたときにこのスレッドに出くわしました。この問題は、Java バイトが 127 を超えているかどうかを判断しようとしているだけです。
簡単な解決策は次のとおりです。
if((val & (byte)0x80) != 0) { ... }
実際の問題が >128 である場合は、その if ステートメントに別の条件を追加するだけでうまくいきます。
ショートを使って保存できると思います。あまり効率的ではありませんが、私が見たいくつかの大変な努力以外の唯一の選択肢です。