プロが教える店舗&オフィスのセキュリティ対策術

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変数の比較で、他に効率のよい方法はりませんでしょうか?

A 回答 (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" 等で必要であれば調べて下さい。  
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
逆アセしてもうすこし深くさぐってみたいと思います。
ありがとうございます。

お礼日時:2009/11/16 22:57

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処理部が効いてしまっているのですかね。

補足日時:2009/11/13 22:01
    • good
    • 0

#1です。


ちょっとお詫びと訂正。
/**
* 偶数 > 奇数である比較規則を定義する。
*
ではなく、

/**
* 負数 > 正数である比較規則を定義する。
*

でした。
    • good
    • 0
この回答へのお礼

ご丁寧にありがとうございます。

お礼日時:2009/11/13 22:10

う~む?こんな関数を作ってみるのも一案ですが、どっちが非効率だか判りませんね。




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
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
新しい手法ですね。助かります。

しかし簡単に試してみたところ、残念ですがおおよそ3.5倍ほど遅いようでした。

お礼日時:2009/11/13 18:40

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!