0

intをバイト配列に変換するために、次のコードを使用しています。

int a = 128;
byte[] b = convertIntValueToByteArray(a);
private static byte[] convertIntValueToByteArray(int intValue){
  BigInteger bigInteger = BigInteger.valueOf(intValue);
  byte[] origByteArray = bigInteger.toByteArray();
  byte[] noSignByteArray = new byte[bigInteger.bitLength()/8];

  if(bigInteger.bitLength()%8!=0){
    noSignByteArray = origByteArray;
  }else{
    System.arraycopy(origByteArray,1,noSignByteArray,0,noSignByteArray.length);
  }

  return noSignByteArray;
}

私がやろうとしていることは2つあります。

1)元の整数のバイト数(クローズバイトに切り上げ)を知る必要があります。ただし、toByteArray()メソッドを呼び出すときに符号ビットに追加される追加ビットは必要ありません。これが私がヘルパーメソッドを持っている理由です。したがって、この例では、ヘルパーメソッドがない場合、128をバイト配列に変換すると、符号ビットのために長さが2オクテットになりますが、期待しているのは1オクテットだけです。

2)数字の正の表現が必要です。この例では、配列bの最初の要素を出力しようとすると、-128になります。ただし、使用する数値は正の数のみであるため、実際に必要なのは128です。バイト配列の使用に制限されています。これを達成する方法はありますか?

更新された投稿

ご回答ありがとうございます。探していた正確な答えが見つからなかったので、詳細を説明します。最終的には、データ出力ストリームにさまざまなタイプの値を書き込みたいと思います。この投稿では、intがデータ出力ストリームに書き込まれるとどうなるかを明らかにしたいと思います。私は2つのシナリオに出くわしました。

1)

DataOutputStream os = new DataOutputStream(this.socket.getOutputStream());

byte[] b = BigInteger.valueOf(128).toByteArray();

os.write(b);

2)

DataOutputStream os = new DataOutputStream(this.socket.getOutputStream());
os.write(128);

最初のシナリオでは、バイトがデータ入力ストリームから読み取られるとき、バイト配列の最初の要素はmsbを表す0であり、配列の2番目の要素には数値-128が含まれているようです。ただし、msbは0であるため、正の数であることが意図されていると判断できます。2番目のシナリオでは、msbはなく、入力ストリームから読み取られたバイト配列に存在する要素は-128のみです。データ出力ストリームのwrite()メソッドが、BigIntegerオブジェクトでtoByteArray()メソッドが行うのと同じ方法でintをバイト配列に変換することを期待していました。ただし、msbが存在しないため、これは当てはまらないようです。したがって、私の質問は、2番目のシナリオで、msbがない場合、128は正の数であり、負の数ではないことをどのように知る必要があるかということです。

4

3 に答える 3

4

あなたはおそらくすでに知っているように

  • オクテットでは、パターン10000000は、外部の解釈に応じて、128または-128のいずれかとして解釈できます。
  • Javaのbyteタイプは、オクテクトを-128...127の値としてのみ解釈します。

全世界が非負の整数のみで構成されるアプリケーションを構築している場合、バイト値-128は128を意味し、-127は129を意味し、...および- 1は255を意味します。これは確かに実行可能ですが、作業が必要です。

このような「符号なしバイト」の概念の処理は、通常、バイトをaに拡張するshortint、上位ビットをすべてゼロに設定してから、算術演算を実行するか、値を表示することによって行われます。配列内の2つのオクテットとして128を表すだけでなく、そのようなアプローチが好みに合っているかどうかを判断する必要があります。

于 2012-05-28T19:56:55.420 に答える
2

次のコードで十分だと思います。

Javaでは、 intは2を補う2進数です。

-1              = 111...111
ones complement = 000...000; + 1 =
1               = 000...001

ですから、符号ビットについてはわかりません。それで、あなたができることMath.abs(n)バイトの範囲は-128〜127ですが、解釈は以下のようにマスキングの問題です。

public static void main(String[] args) {
    int n = 128;

    byte[] bytes = intToFlexBytes(n);
    for (byte b: bytes)
        System.out.println("byte " + (((int)b) & 0xFF));
}

public static byte[] intToFlexBytes(int n) {
    // Convert int to byte[4], via a ByteBuffer:
    byte[] bytes = new byte[4];
    ByteBuffer bb = ByteBuffer.allocateDirect(4);
    bb.asIntBuffer().put(n);
    bb.position(0);
    bb.get(bytes);

    // Leading bytes with 0:
    int i = 0;
    while (i < 4 && bytes[i] == 0)
        ++i;

    // Shorten bytes array if needed:
    if (i != 0) {
        byte[] shortenedBytes = new byte[4 - i];
        for (int j = i; j < 4; ++j) {
            shortenedBytes[j - i] = bytes[j]; // System.arrayCopy not needed.
        }
        bytes = shortenedBytes;
    }
    return bytes;
}
于 2012-05-28T20:31:41.207 に答える
1

最初の質問(符号なし表現を使用して非負の整数を表すのに必要なバイト数)に答えるために、私がCommonLispで書いた次の関数を検討してください。

(defconstant +bits-per-byte+ 8)

(defun bit-length (n)
  (check-type n (integer 0) "a nonnegative integer")
  (if (zerop n)
      1
      (1+ (floor (log n 2)))))

(defun bytes-for-bits (n)
  (check-type n (integer 1) "a positive integer")
  (values (ceiling n +bits-per-byte+)))

これらは、問題の数学的基盤を浮き彫りにします。つまり、対数は、与えられた非負の整数を支配するのに必要な2の累乗(ビットによって提供される)を示し、でステップ関数になるように調整され、必要なfloorバイト数を示します。そのビット数をステップ関数として再び保持するために、今回は。で調整しceilingます。

数値ゼロは対数関数への入力として許容できないため、明示的に回避することに注意してください。bit-lengthコア式をわずかに変換して関数を記述できることもわかります。

(defun bit-length-alt (n)
  (check-type n (integer 0) "a nonnegative integer")
  (values (ceiling (log (1+ n) 2))))

残念ながら、1の対数はベースに関係なく常にゼロであるため、このバージョンでは、整数のゼロはゼロビットで表すことができるとされていますが、これは私たちが望む答えではありません。

2番目の目標として、上記で定義した関数を使用して、必要なバイト数を割り当て、符号を無視して必要なビットを段階的に設定できます。バイトベクトルに適切なビットを設定するのに問題があるのか​​、それとも上位ビットを符号ビット(つまり、2の補数表現)として扱わないようにビットを解釈するのに問題があるのか​​を判断するのは困難です。再び動くために必要なプッシュの種類を詳しく説明してください。

于 2012-05-28T20:55:00.930 に答える