あるバイトから次のバイトに転送されているビットを本当に知りたい場合を除き、この方法を使用しないことをお勧めします! 単純な計算の場合は、配列を実数 short
とint
型に変換し、計算を行ってから、再度変換してください。
このようにする必要がある場合は、次の点を考慮してください。
配列short
内にある 2 つの変数を追加しているイメージ。byte
最初の問題は、すべての Java 整数型が署名されていることです。
2 つ目は、最下位バイトから最上位バイトへの「キャリー」は、オーバーフローを検出できないため、aよりも長い型を使用して行うのが最適です。byte
つまり、2 つの 8 ビット値を加算すると、キャリーはビット 8 になります。ただし、 a にbyte
はビットしかない0..7
ため、ビット 8 を計算するには、バイトを次に適切なより大きな型に昇格させ、加算操作を行ってから計算する必要があります。キャリーが発生した場合は、MSB を合計するときにそれを処理します。それだけの価値はありません。
ところで、私は何年も前に MC6809 CPU エミュレーターを作成したときに、この種のビット操作を実際に行う必要がありました。同じビットがハードウェア ALU によって「無料で」生成される場合、CPU のさまざまなステータス ビットへの影響を把握できるようにするためだけに、同じオペランドに対して複数の操作を実行する必要がありました。
たとえば、2 つの 8 ビット レジスタを追加する私の (C++) コードは次のようになります。
void mc6809::help_adc(Byte& x)
{
Byte m = fetch_operand();
{
Byte t = (x & 0x0f) + (m & 0x0f) + cc.bit.c;
cc.bit.h = btst(t, 4); // Half carry
}
{
Byte t = (x & 0x7f) + (m & 0x7f) + cc.bit.c;
cc.bit.v = btst(t, 7); // Bit 7 carry in
}
{
Word t = x + m + cc.bit.c;
cc.bit.c = btst(t, 8); // Bit 7 carry out
x = t & 0xff;
}
cc.bit.v ^= cc.bit.c;
cc.bit.n = btst(x, 7);
cc.bit.z = !x;
}
これは、 ,およびフラグを抽出するためだけに、オペランドのさまざまなバリエーションに対して3 つの異なる加算を行う必要があります。h
v
c