7

C Traps and PitfallsAndrewKoeningの本のCポータビリティに関するセクションを読んでいました。

整数除算について

q = a/b;
r = a%b;

aが負の数の場合、リマインダーrは、プロパティを満たしながら、負または正の数になる可能性があります。

q * b + r == a

通常、配当aが負の場合、 rは負になると予想します。そして、それは私がgccを備えたIntelマシンで見るものです。配当が負の数の場合に正のリマインダーを返すマシンを見たことがありますか?

4

1 に答える 1

9

C99は、剰余を配当と同じ符号を持つものとして形式化しました。C99(C89およびK&R)より前は、両方の結果が技術要件を満たしているため、どちらの方向にも進んでいた可能性があります。確かに、この件に関してC99仕様に準拠していないコンパイラがありますが、頭の中で何も知りません。

特に、セクション6.5.5(乗法演算子)には次のように記載されています。

¶5/演算子の結果は、最初のオペランドを2番目のオペランドで除算した商です。%演算子の結果は剰余です。どちらの操作でも、第2オペランドの値がゼロの場合、動作は定義されていません。

¶6整数を除算すると、/演算子の結果は、小数部分が破棄された代数商になります。87)a/bが表現可能である場合、式 (a/b)*b + a%bはに等しくなりaます。

87)これはしばしば「ゼロへの切り捨て」と呼ばれます。

この新しい定義では、余りは基本的に、数学的に言えば期待できるものとして定義されます。

編集

コメントの質問に対処するために、C99仕様では、余りがゼロの場合、ゼロが符号付けされていないシステムでは、rの符号は除数xの符号と同じになることも指定されています(脚注240)。

'' y≠0の場合、余りr = x REM yは、丸めモードに関係なく、数学的な関係r = x − nyによって定義されます。ここで、nはx/yの正確な値に最も近い整数です。いつでも| n − x / y | = 1/2の場合、nは偶数です。したがって、余りは常に正確です。r = 0の場合、その符号はxの符号になります。''この定義は、すべての実装に適用されます。

于 2012-04-05T06:21:46.827 に答える