18

バイトがオーバーフローすると実際に何が起こりますか?

私たちが持っていると言う

byte byte1 = 150; // 10010110  
byte byte2 = 199; // 11000111

今この追加を行う場合

byte byte3 = byte1 + byte2;

最終的にbyte3=94になると思いますが、実際にはどうなりますか?どういうわけか他のメモリを上書きしましたか、それともこれは完全に無害ですか?

4

12 に答える 12

14

とても簡単です。足し算をするだけで、8ビット以上の数字で外れます。9番目のビット(1つである)は「落ちる」だけで、残りの8ビットが残り、番号94を形成します。

(はい、無害です)

于 2010-11-11T16:58:40.230 に答える
8

上位ビットは切り捨てられます。他のメモリに害を及ぼすことはなく、意図しない結果の観点からのみ害を及ぼします。

于 2010-11-11T16:59:07.233 に答える
6

C#では

 checked { byte byte3 = byte1 + byte2; }

オーバーフロー例外がスローされます。コードはuncheckedデフォルトでコンパイルされます。他の答えが言っているように、値は「ラップアラウンド」します。すなわち、byte3 = (byte1 + byte2) & 0xFF;

于 2010-11-11T17:00:52.553 に答える
5

キャリーフラグが設定されます...しかし、期待どおりの結果が得られないことを除けば、悪影響はないはずです。

于 2010-11-11T16:59:05.993 に答える
5

通常(正確な動作は言語とプラットフォームによって異なります)、結果はモジュロ256で取得されます。つまり、150 +199=349。349mod256=93。

これは他のストレージには影響しません。

于 2010-11-11T17:00:03.913 に答える
5

質問にC#、C ++、Cのタグを付けたので、CとC++について回答します。C ++では、署名された型のオーバーフロー( C / C ++にsbyteあると思います)を含めると、未定義の動作が発生します。signed charただし、byteunsigned charC ++にある)などの符号なし型の場合、結果はモジュロ2 nになります。ここで、nは符号なし型のビット数です。C#では、2番目のルールが適用され、署名された型がブロック内にある場合は例外が生成されcheckedます。C#の部分が間違っている可能性があります。

于 2010-11-11T17:00:36.520 に答える
4

オーバーフローはc#では無害です-メモリをオーバーフローさせることはありません-結果の最後の8ビットを取得するだけです。これを例外にしたい場合は、「checked」キーワードを使用してください。また、byte + byteがintを与えることがあるので、byteにキャストバックする必要があるかもしれないことにも注意してください。

于 2010-11-11T17:01:16.487 に答える
3

動作は言語によって異なります。

CおよびC++では、符号付きオーバーフローは未定義であり、符号なしオーバーフローは前述の動作をします(タイプはありませんがbyte)。

C#では、キーワードを使用して、checkedオーバーフローが発生した場合に例外を受信することを明示的に指定し、キーワードを使用して、例外uncheckedを無視することを明示的に指定できます。

于 2010-11-11T17:00:05.987 に答える
2

先頭ビットが落ちたところです。

于 2010-11-11T16:59:06.927 に答える
2

そして、算術オーバーフローが発生します。150 + 199 = 349、バイナリ1 0101 1101であるため、上位1ビットはドロップされ、バイトは01011101になります。つまり、1バイトが保持できるビット数がオーバーフローしました。

損傷はありませんでした。たとえば、メモリが別の場所にオーバーフローしませんでした。

于 2010-11-11T17:00:36.800 に答える
1

実際に何が起こるかを見てみましょう(Cでは(適切なデータ型があると仮定します。Cには「バイト」データ型がないという指摘もありますが、追加できる8ビットデータ型があります)) 。これらのバイトがスタックで宣言されている場合、それらはメインメモリに存在します。ある時点で、バイトは操作のためにプロセッサにコピーされます(プロセスやキャッシュなど、いくつかの重要な手順をスキップしています...)。プロセッサに入ると、それらはレジスタに格納されます。プロセッサは、これら2つのレジスタに対して加算操作を実行して、データを加算します。 ここで混乱の原因が発生します。 CPUは、ネイティブ(または場合によっては指定された)データ型で追加操作を実行します。CPUのネイティブタイプが32ビットワードであるとしましょう(そして、そのデータ型が追加操作に使用されるものです)。つまり、これらのバイトは、上位24ビットが設定されていない32ビットワードで格納されます。追加操作は、実際にターゲットの32ビットワードでオーバーフローを実行します。ただし、(これが重要なビットです)データがレジスタからスタックにコピーバックされると、最下位8ビット(バイト)のみがスタック上のターゲット変数の位置にコピーバックされます。(ここでも、バイトパッキングとスタックに複雑さが伴うことに注意してください。)

それで、これが結果です。追加によりオーバーフローが発生します(選択した特定のプロセッサ命令によって異なります)。ただし、データはプロセッサから適切なサイズのデータ​​型にコピーされるため、オーバーフローは認識されません(適切に記述されたコンパイラを想定すると、無害です)。

于 2010-11-11T17:14:42.987 に答える
1

C#に関する限り、typeの2つの値を足しbyte合わせると、typeの値が生成され、intこれをにキャストバックする必要がありbyteます。

したがって、コードサンプルでは、​​次のようにバイトにキャストバックせずにコンパイラエラーが発生します。

byte byte1 = 150; // 10010110  
byte byte2 = 199; // 11000111

byte byte3 = (byte)(byte1 + byte2);

詳細については、MSDNを参照してください。また、C#言語仕様のセクション7.3.6数値プロモーションも参照してください。

于 2011-10-12T20:04:11.763 に答える