プロセスの理解と0xff

大規模な割り当てを作成するとき、&0xffの動作は常に疑問視されていました。
バイト[i]は8ビットバイナリであり、8ビットバイナリに変換された0xffは11111111なので、バイト[i]と0xffはまだバイト[i]自体ではないですか?

冗談ですか?
4バイトをint型に変換します
この問題について、私はオンラインでのデモが非常に興味深いことを知りました。

#include<stdio.h>
int main(void)
{
     char byte = -127;
     int a;
     a = byte;
     printf("%d\n", a);
     a = byte & 0xff;
     printf("%d", a);
     
     return 0;
}

しかし〜
ここに画像の説明を挿入
物事は面白くなり始めました...

&0xffを追加するのはなぜ間違っているのですか?

最初補完の概念を確認ましょう

正の数(00000001)の元のコードの場合、最初のビットは符号ビットを表し、逆数と補数は両方ともそれ自体です。
負の数の元のコード(100000001)の場合、逆符号は、符号ビットを除く元の符号の逆演算です。 (111111110)次に+1演算を実行します(すなわち(111111111)

次にシンボル拡張の概念を紹介します。

8ビットの2進数を例にとると、符号拡張とは、現在の値を変更せずに、それらを16ビットおよび32ビットの2進数に変換することを指します。規則は、それが正の数であるか、補数で表される負の数であるかにかかわらず、必要なことは、上位ビットに符号ビットの値(0または1)を入力することだけです。

トピックを入力してください:

-127がバイトに割り当てられている場合、バイトはchar型であり、そのコンピューターの補数は10000001(8ビット)です[コンピューターでは、負の数は補数の形式で格納されます]。

  a = byte;//-127

最初にバイトがint型としてコンソールに出力されたとき、コンパイラーは符号拡張プロセスを行いました。int型は32ビットの2進数であるため、バイト拡張の補数は1111111111111111111111111 10000001(32ビット)です。 32ビットの2の補数で表される10進数も-127です。これは、符号拡張が対応する10進数の現在の値に影響を与えないことを意味します。

これは非常に優れた特性ですが、char型をint型に変換する場合、目的は対応する10進数の不変性を保証することだけではありません。たとえば、今回の大きな仕事は、4つの文字型を1つのint型に変換することです。これは、2の補数の一貫性を保証する必要があります。つまり、4つの文字型に対応するバイナリ01シーケンスはそのままです。 int型の4バイトのバイナリシーケンスとして(8ビットの上位8ビットと下位8ビット)。

    a = byte & 0xff;//129

では、2回目に値を割り当てるときになぜ値を変更するのでしょうか。
詳細に分析してみましょう。
シンボル拡張の概念を導入する前に、バイト(10000001)がintに変換されると、上位24ビットは必然的に1で埋められます。このようにして、その2つの補数は実際に変更されました。&0xff(11111111)はバイトをintに変更できますが、上位24ビットは0に設定され、下位8ビットはそのまま残ります。

それから、何人かの学生は疑問に思うかもしれません:0xffである24ビットが1と同じ高さでないのはなぜですか?これは、0xffまたは0xFF自体が32ビット長のintリテラル定数であるため、符号拡張されないためです。

もちろん、2の補数の一貫性を確保したい場合、2進数に対応する10進数は自然に変化します。両方を持つことは不可能です〜

コードの特定の実装を見てみましょう:

    a = byte & 0xff;//129

バイト&0xff = 111111111111111111111111110000001&11111111
= 000000000000000000000000 10000001

2進数の重みは129です。

これは、&0xffを追加するとエラーが発生する理由の良い説明です。

この時点でのプログラムは、対応する10進数の整合性ではなく、2の補数の整合性を保証するためです。

最後

大きなジョブの変換アルゴリズムの問​​題に戻りましょう。2の補数の整合性を確保したいので、最初にバイトに対して&0xff演算を実行する必要があります。もちろん、バイトの符号ビットが0の場合、&0xffは意味がありません。しかし、バイトの符号ビットが1の場合は、最終的に値との論理OR演算を実行するため、それを比較検討する必要があります(たぶん、取得するために努力してきたバイナリシーケンスはすべて1になります)。 )!

元の記事を1件公開 賞賛7件 訪問数153件

おすすめ

転載: blog.csdn.net/Ziyang1060/article/details/105567083