我々はすべて知っ0/0
ているUndefined
と私は電卓にそれを入れていた場合はエラーを返し、私はプログラムを作成した場合、私はゼロによる除算しようとすると、(Cで少なくとも)OSは、それを終了します。
しかし、私が考えていたのは、コンピューターがゼロで除算しようとするのか、それとも「組み込みの保護」があるだけなのか、それ0/0
を計算しようとする前でもエラーを返すのですか?
我々はすべて知っ0/0
ているUndefined
と私は電卓にそれを入れていた場合はエラーを返し、私はプログラムを作成した場合、私はゼロによる除算しようとすると、(Cで少なくとも)OSは、それを終了します。
しかし、私が考えていたのは、コンピューターがゼロで除算しようとするのか、それとも「組み込みの保護」があるだけなのか、それ0/0
を計算しようとする前でもエラーを返すのですか?
回答:
CPUには検出機能が組み込まれています。ほとんどの命令セットアーキテクチャでは、CPUがゼロによる整数除算の例外ハンドラーにトラップするように指定されています(被除数がゼロであるかどうかは気にしません)。
除数の試みと並行してゼロ除数のチェックがハードウェアで並行して行われる可能性がありますが、問題のある状態の検出により、代わりに除算とトラップが事実上キャンセルされます。その分割を試みたかどうか。
(ハードウェアは多くの場合そのように機能し、複数のことを並行して行い、その後適切な結果を選択します。これは、適切な操作の選択でシリアル化する代わりに、各操作をすべてすぐに開始できるためです。)
オーバーフロー検出がオンになっている場合も、例外メカニズムへの同じトラップが使用されます。通常、オーバーフロー要求は、異なるadd / sub / mul命令(またはそれらの命令のフラグ)を使用して要求します。
浮動小数点除算にはゼロ除算の検出機能も組み込まれていますが、例外ハンドラーにトラップする代わりに、異なる値(IEEE 754がNaNを指定)を返します。
仮に言えば、CPUがゼロ除算の試みの検出を省略した場合、問題には以下が含まれます。
言語、コンパイラ、整数または浮動小数点数のいずれを使用しているかなどに依存します。
浮動小数点数の場合、ほとんどの実装はIEEE 754標準を使用し、0による除算が明確に定義されています。0/0はNaN(not-a-number)の明確な結果を提供し、x≠0のx / 0はxの符号に応じて+ Infinityまたは-Infinityを提供します。
C、C ++などの言語では、ゼロによる除算は未定義の動作を呼び出します。したがって、言語の定義によれば、何でも起こり得ます。特に、起こりたくないこと。コードを書くときにすべてが完璧に機能し、顧客がそれを使用するときにデータを破壊するように。したがって、言語の観点からは、これを行わないでください。一部の言語では、アプリケーションがクラッシュすることが保証されています。これがどのように実装されるかは彼ら次第です。これらの言語では、ゼロによる除算がクラッシュします。
多くのプロセッサには、プロセッサに応じて異なる動作をする組み込みの「除算」命令があります。Intel 32ビットおよび64ビットプロセッサでは、ゼロで除算しようとすると、「除算」命令によってアプリケーションがクラッシュします。他のプロセッサの動作は異なる場合があります。
コンパイラーは、コードの実行時にゼロによる除算が発生することをコンパイラーが検出し、コンパイラーがユーザーに良い場合、警告を出し、組み込みの「除算」命令を生成して動作が同じ。
EXCEPTION_INT_DIVIDE_BY_ZERO
値ですEXCEPTION_RECORD
しかし、私が疑問に思っているのは、コンピューターがゼロで除算しようとするのか、それとも「組み込みの保護」があるだけなのか、0/0を「見る」ときに計算を試みる前でもエラーを返すということです。
x/0
意味のない期間なので、コンピューターは常にゼロによる除算をチェックする必要があります。ここに問題があります:プログラマーは(a+b)/c
、その計算が理にかなっているかどうかをわざわざ確認する必要なく計算することを望みます。CPU +数値型+オペレーティングシステム+言語によるゼロ除算に対する内部の応答は、かなり抜本的な処理(プログラムのクラッシュなど)を行うか、過度に良性の処理(例: IEEE浮動小数点などの意味NaN
、「Not a Number」)。
通常の設定では、プログラマは(a+b)/c
理にかなっているかどうかを知ることが期待されます。このコンテキストでは、ゼロによる除算を確認する理由はありません。ゼロによる除算が行われ、マシン言語+実装言語+データ型+これに対するオペレーティングシステムの応答がプログラムをクラッシュさせる場合は、問題ありません。応答が、プログラム内のすべての数値を最終的に汚染する可能性のある値を作成することである場合、それも問題ありません。
高信頼性コンピューティングの世界では、「抜本的な」ことも「過度に優しい」ことも正しいことではありません。これらのデフォルトの応答は、患者を殺したり、旅客機をcrash落させたり、間違った場所で爆弾を爆発させたりする可能性があります。信頼性の高い環境では、書き込みを(a+b)/c
行うプログラマはコードレビュー中に死に至るか、現代では、詳細な構成をチェックするツールによって自動的に死に至る可能性があります。この環境では、そのプログラマーは代わりに何かの行div(add(a,b),c)
(および場合によってはエラーステータスのチェック)を記述する必要があります。フードの下で、div
(およびadd
)関数/マクロはゼロによる除算(またはの場合はオーバーフロー)から保護しますadd
。その保護が伴うものは、実装固有のものです。
私たちは今ではそれを知っており、明確な答えはx/0
あり0/0
ません。0/0
とにかく計算しようとするとどうなりますか?
最新のシステムでは、計算はCPU内のMPUに渡され、不正な操作としてフラグが立てられ、を返しNaN
ます。
オンチップ部門を持たない80年代のホームコンピューターなど、はるかに古いシステムでは、実行中のソフトウェアにかかわらず計算が行われました。いくつかの選択肢があります。
0
1
log(0)
あり、ソフトウェアはエラー処理ルーチンを使用するか、クラッシュします0
e 0 = 1となり、次の結果が得られます。1
言い換えれば、何が起こるかは実装に依存し、すべての値に対して正しい予測可能な結果を生成するソフトウェアを作成することは可能ですが0/0
、それでもなお一見奇妙な値は内部的に一貫しています。
NaN
であり、整数のようなものはありません。
very inefficient
除算のためであると答えました。算術のコストは(加算=減算)<=乗算<=除算です。加算と同じクロックサイクル数(通常は1)で除算できるMPUがない場合、除算は加算と減算よりも高価で、通常は乗算よりも高価です。