5

私は、C標準(C90、ただしDerek Jonesの注釈付きC99ブックを使用しています)が、2つの符号なし8ビット値を乗算して16ビット結果に格納する精度を失わないことを保証するかどうかを理解しようとしています。ステートメントの例は次のとおりです。

unsigned char foo;
unsigned int foo_u16 = foo * 10;

当社のKeil8051コンパイラ(現在はv7.50)は、MSBをBレジスタに、LSBをアキュムレータに格納するMULAB命令を生成します。最初にfooをunsignedintにキャストした場合:

unsigned int foo_u16 = (unsigned int)foo * 10;

次に、コンパイラは、そこにunsigned intが必要であると正しく判断し、16x16ビット整数乗算ルーチンへの高価な呼び出しを生成します。合理的な疑いを超えて、この防御策は必要ないということを主張したいと思います。6.3.1.1で説明した整数昇格を読んだとき、最初の行の効果は、fooと10がunsigned intに昇格され、乗算が実行され、結果がfoo_u16にunsignedintとして格納されたかのようになります。コンパイラが、精度を損なうことなく8x8-> 16ビットの乗算を行う命令を知っている場合は、はるかに優れています。ただし、精度は保証されています。私はこれを正しく読んでいますか?

よろしく、クレイグブロム

4

1 に答える 1

5

昇格は保証されますが、 の範囲が の範囲に収まるsigned int場合、昇格はタイプに行われます。だから(それが合っていると仮定して)言語の観点からあなたのunsigned charsigned int

unsigned int foo_u16 = foo * 10; 

と同等です

unsigned int foo_u16 = (signed) foo * 10; 

あなたが明らかに望んでいるのは

unsigned int foo_u16 = (unsigned) foo * 10; 

乗算の結果 (結果) が範囲に収まらない場合、異なる結果になる可能性がありsigned intます。

unsigned charコンパイラの解釈が異なる場合は、コンパイラのバグである可能性があります (ここでも、 の範囲がの範囲に収まるという仮定の下でsigned int)。

于 2010-04-22T18:59:11.187 に答える