![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
2つのbyte変数の比較を行いたいのですが、
byte aaa = 0x00;
byte bbb = (byte)0xff;
if(aaa > bbb){
処理
}
のようにするとbyteの最上位bitは符号として扱われるため
0xff=-127となってしまい意図した結果が得られません。
unsigned byteなるものがあれば都合がよいのですが、javaではサポートしておらず困っております。
代替案として、
if(aaa&0xff > bbb&0xff)
などとして、一度intへ変換後比較すれば可能ですが、int用のメモリ領域を作成しなくてはならず、非効率の気がします。
byte変数の比較で、他に効率のよい方法はりませんでしょうか?
No.3ベストアンサー
- 回答日時:
f(aaa&0xff > bbb&0xff)
このままで良いですよ。
JavaVMが実行時にレジスタ内部で(aaa & 0xff)の演算を、bbbについても同じくやった後、直接レジスタ同士の比較をやるように、各マシン毎にマシン命令に変換しますから、そのままが一番早いはずです。
従ってこの演算用のint用のメモリ領域は不要です。
unsigned byte,int等が無いためにa=0x12,b=0x81の2バイトから
(a<<8)|b ==>0xff81が得られて困っている人がいたりします。
何でunsigned byte,int,long dataが規格に入っていないのでしょうね?
この回答への補足
ご回答ありがとうございます。
そうですか。ではこのままが一番でファイナルアンサーなのですかね。
同処理を何百単位で繰り返し実行させた場合、JITコンパイルされる事を考えると、Cで同じ事をさせた場合と同じような結果を期待したのですが、Javaの方が数倍遅い結果となりました。これは byte->int処理部が効いてしまっているのですかね。
No.4
- 回答日時:
> byte->int処理部が効いてしまっているのですかね。
そのようですね。
C の場合は
load reg,aaa; comp reg,bbb の2命令で
Java の場合
load reg0,aaa;
(if not sign extended load & aaa>0x7f, sign extend)
andi reg0,0xff
load reg1,bbb
...
comp reg0,reg1
のようになると思います。
(...) の部分は後に続くのがバイトマスク命令であれば省けるはずですが、無条件にsign extended 32bit int に変換するだけだったらそのまなので時間がかなり余分にかかるでしょうね。
"java 逆アセンブラ"、"java 逆コンパイラ", "java virtual machine specification", "java JIT compiler" 等で必要であれば調べて下さい。
No.1
- 回答日時:
う~む?こんな関数を作ってみるのも一案ですが、どっちが非効率だか判りませんね。
public class testbyte {
/**
* @param args
*/
public static void main(String[] args) {
byte[] aaa = newbyte [] {
(byte)0x00, (byte)0x01, (byte)0x02,
(byte)0x03, (byte)0x7f, (byte)0x80,
(byte)0x81, (byte)0xfe, (byte)0xff};
String[] sss = newString [] {
"00", "01", "02",
"03", "7F", "80",
"81", "FE", "FF"};
for(int lp=0;lp<aaa.length;lp++){
for(int i=0;i<aaa.length;i++){
System.out.print(sss[lp]);
intret=compare(aaa[lp],aaa[i]);
if(ret<0){
System.out.print(" < ");
}else if(ret>0){
System.out.print(" > ");
}else{
System.out.print(" = ");
}
System.out.println(sss[i]);
}
}
}
/**
* 偶数 > 奇数である比較規則を定義する。
*
* @param i1 比較する最初の項
* @param i2 比較する二番目の項
* @return i1 が負数かつ i2 が正であれば 1
* i1 が正数かつ i2 が負数であれば -1
* 両方とも正数の場合は自然順序に従う
* 両方とも負数の場合は自然順序に従う
*/
publicstatic int compare(byte i1, byte i2){
if((i1<0) && (i2>=0)) return 1;
if((i1>=0) && (i2<0)) return -1;
return (i1 - i2);
}
}
00 = 00 00 < 01 00 < 02 00 < 03 00 < 7F 00 < 80 00 < 81 00 < FE 00 < FF
01 > 00 01 = 01 01 < 02 01 < 03 01 < 7F 01 < 80 01 < 81 01 < FE 01 < FF
02 > 00 02 > 01 02 = 02 02 < 03 02 < 7F 02 < 80 02 < 81 02 < FE 02 < FF
03 > 00 03 > 01 03 > 02 03 = 03 03 < 7F 03 < 80 03 < 81 03 < FE 03 < FF
7F > 00 7F > 01 7F > 02 7F > 03 7F = 7F 7F < 80 7F < 81 7F < FE 7F < FF
80 > 00 80 > 01 80 > 02 80 > 03 80 > 7F 80 = 80 80 < 81 80 < FE 80 < FF
81 > 00 81 > 01 81 > 02 81 > 03 81 > 7F 81 > 80 81 = 81 81 < FE 81 < FF
FE > 00 FE > 01 FE > 02 FE > 03 FE > 7F FE > 80 FE > 81 FE = FE FE < FF
FF > 00 FF > 01 FF > 02 FF > 03 FF > 7F FF > 80 FF > 81 FF > FE FF = FF
ご回答ありがとうございます。
新しい手法ですね。助かります。
しかし簡単に試してみたところ、残念ですがおおよそ3.5倍ほど遅いようでした。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
javaで質問です。 文字列2023/2...
-
JavaのStringクラスに「外字」...
-
Jquery 文字列>画像に変換したい
-
IBM漢字コード⇒SJIS変換方法
-
javascriptで文字列のsjis利用...
-
int型のゼロ埋め
-
Path型をString型へ変換する(Java)
-
javaの初歩的な質問です。
-
ダブルクォーテーションのrepla...
-
タイピングゲーム作成中 複数...
-
COBOLで半角カナを全角カナに変換
-
PerlプログラムをJavaに変換す...
-
秒を時分秒へ変換
-
char型からアスキーコードへの変換
-
UTF-8とUnicodeの互換性
-
Javaで、画面入力したデータを...
-
Vivus.jpでアニメーションを作...
-
javaの文字コード変換表はどこ...
-
Visual Basic でのコードをASCI...
-
エクセルVBAで「〜」が表現でき...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
javaで質問です。 文字列2023/2...
-
ダブルクォーテーションのrepla...
-
Path型をString型へ変換する(Java)
-
カタカナをローマジに変換する。
-
int型のゼロ埋め
-
javascriptで文字列のsjis利用...
-
Visual Basic でのコードをASCI...
-
C言語32bitから64bitの移行につ...
-
substring バイト単位でやりたい
-
JavaのStringクラスに「外字」...
-
COBOLで半角カナを全角カナに変換
-
byte[] を long,float とかに...
-
文字列の比較
-
エクセルVBAで「〜」が表現でき...
-
javaで「全角が含まれているか...
-
byte配列をImageに変換する
-
javaの初歩的な質問です。
-
文字化けします。
-
DBから取得したデータの文字化け
-
[Javascript]エンターキー押下...
おすすめ情報