私は疑問を持っています
2 つの 16 ビット値を最大値で加算すると、16 ビット マシンでオーバーフローが発生しますか?
詳しく説明します
unsigned short a;
unsigned short b;
unsigned long c;
c=(unsigned long)(a+b);
16 ビット プロセッサについて言えば、アキュムレータは 16 ビット サイズになります。上記のステートメントでオーバーフローが発生しますか? どうか明らかにしてください。
私は疑問を持っています
2 つの 16 ビット値を最大値で加算すると、16 ビット マシンでオーバーフローが発生しますか?
詳しく説明します
unsigned short a;
unsigned short b;
unsigned long c;
c=(unsigned long)(a+b);
16 ビット プロセッサについて言えば、アキュムレータは 16 ビット サイズになります。上記のステートメントでオーバーフローが発生しますか? どうか明らかにしてください。
これらの定義を使用し、unsigned short
== 16 ビットおよびint
== 16 ビットおよびunsigned long
== 32 ビットと仮定すると (サイズが重要であることに注意してくださいint
):
unsigned short a, b;
unsigned long c;
これらの 2 つのステートメントは、異なることを行います。
c = (unsigned long)(a + b);
c = (unsigned long)a + b;
最初のもの-あなたが示したもの-は、最初に数字をunsigned shortとして追加し、オーバーフローを破棄します-次に、unsigned longに展開します。これがあなたが尋ねている理由かもしれません。2 番目は unsigned long にキャストa
してから、2 つの数値を加算し、b
unsigned long に展開してから加算を行います。
これを行うこともできます:
c = (unsigned long)a + (unsigned long)b;
ただし、計算に 1 つの unsigned long が存在すると、もう 1 つのサイズが short から long に自動的に昇格されるため、これは不要です。
したがって:
a = 0x8001;
b = 0x8001;
c = (unsigned long)(a + b); /* c is assigned 0x00000002 */
c = (unsigned long)a + b; /* c is assigned 0x00010002 */
これはすべて、特定のコンパイラとその変数のサイズに依存します。int
すべての値は計算中int
または計算中に自動的にプロモートされるため、特にコンパイラの のサイズに依存しますunsigned int
。16ビットアキュムレータを備えたハードウェアについて言及しましたが、Cコンパイラは通常(常にではありませんが)ネイティブレジスタサイズを のサイズとして使用します。そのため、を16ビットint
と仮定しました。int
はい、オーバーフローが発生します。部分式 a + b の型は short であり、評価された後にのみ、結果が long にキャストされます。これを行う:
c = (unsigned long)a + b;
これにより、加算が行われる前に a が a long にキャストされ、これにより b も long にキャストされます。したがって、2 つの long の加算が行われ、オーバーフローは発生しません。