質問

私はしばらくの間C ++でプログラミングをしてきましたが、突然疑いがあり、Stackoverflowコミュニティで明確にしたいと思っていました。

整数が別の整数で分割されると、結果は整数であり、賢明であるように、フロートで分割されたフロートもフロートです。

しかし、この結果を提供する責任者は誰ですか?コンパイラですか、それともDIV命令ですか?

役に立ちましたか?

解決

コンパイラは、コンパイル時に、使用される変数のタイプに基づいてどのような形式が必要かを決定します - 一日の終わりには、Div(またはFDIV)命令が何らかの形で関与します。

他のヒント

それはあなたのアーキテクチャのかどうかに依存します もっている a DIV 命令。アーキテクチャに整数とフローティングポイントの分割命令の両方がある場合、コンパイラはコードで指定されたケースの適切な命令を発します。言語標準は、タイププロモーションのルールを指定し、整数またはフローティングポイント部門を各状況で使用するかどうかを指定します。

整数分裂命令のみ、または浮動小数点分割命令のみがある場合、コンパイラはいくつかのコードをインラインにしたり、数学サポートライブラリへの呼び出しを生成して部門を処理します。除算命令は非常に遅いため、ほとんどのコンパイラーは可能であれば最適化しようとします(たとえば、シフト指示に置き換えるか、コンパイル時間定数の分割の結果を事前に計算します)。

ハードウェアの分割命令には、整数とフローティングポイント間の変換はほとんど含まれません。除算の指示が得られた場合(分割回路が大きくて複雑であるため、それらは時々除外されます)、それらは「intでdivide int、drocement int」と「フロートでフロートを分割し、フロートを生成する」と実際に確信しています。 。そして、通常、入力と出力の両方がすべて同じサイズであるということです。

コンパイラは、これらのプリミティブの上に、ソースコードに記述された操作を構築する責任があります。たとえば、Cでは、フロートをINTで除算すると、コンパイラはfloatの変換とフロートの分割を発します。

(奇抜な例外は存在します。私は知りませんが、私はそれをvaxを超えて「int by int」タイプの命令を持っていたとはしませんでした。イタニウムには実際にはdivide命令がありませんでしたが、その「分割ヘルパー" だった それだけ 浮かぶ点のために、あなたはフロートの分割の上に整数分裂を偽造する必要がありました!)

あなたの質問は本当に意味がありません。 Div命令はありません なんでも それ自体が。どんなに大声で叫んでも、たとえあなたがそれを賄briしようとしたとしても、それは責任を負いません なんでも

プログラミング言語[x]でプログラムするとき、それは[x]コンパイラの唯一の責任です ソースコードで説明したことを行うプログラムを作成します.

部門が要求された場合、コンパイラはディビジョンを実現する方法を決定します。これは、OPCODEを生成することで発生する可能性があります DIV 指示、ターゲットにしているCPUには1つがあります。コンパイル時にディビジョンを事前に計算し、結果をプログラムに直接挿入するだけである可能性があります(両方のオペランドがコンパイル時に知られていると仮定します)、または一緒に一緒になった一連の指示を生成することによって行われる可能性があります。 エミュレート ディビソン。

しかし、そうです いつも コンパイラまで。 C ++プログラムにはありません どれか C ++標準に従って解釈されない限り効果。あなたがそれをプレーンテキストファイルとして解釈する場合、それはしません なんでも. 。コンパイラがJavaプログラムとして解釈すると、それを窒息させて拒否します。

DIV命令は、C ++標準について何も知りません。一方、C ++コンパイラは 書かれています C ++標準を理解し、それに従ってコードを変換することを唯一の目的で。

コンパイラはそうです いつも 責任者。

C ++標準で最も重要なルールの1つは、「あたかい」ルールです。

この国際標準のセマンティックな説明は、パラメーター化された非決定的抽象マシンを定義します。この国際標準は、適合の実装の構造に要件はありません。特に、抽象マシンの構造をコピーまたはエミュレートする必要はありません。むしろ、以下で説明するように、抽象マシンの観測可能な動作を(のみ)エミュレートするには、適合の実装が必要です。

質問に関連して、それが完了している限り、どのコンポーネントが部門を行うかは関係ないことを意味します。 aによって実行される場合があります DIV マシンコード、問題のプロセッサに適切な命令がない場合、より複雑なコードによって実行される場合があります。

それもできます:

  1. 必要に応じて、より高速になる可能性が高い場合は、操作をビットシフト操作に置き換えます。
  2. コンパイル時に計算可能な場合、操作を文字通りに置き換えます。たとえば、x / yを処理する場合は、コンパイル時にyが常に1になることを表示できます。
  3. コンパイル時にゼロによる整数部門になることをコンパイル時に表示できる場合は、操作を例外スローに置き換えます。

特に

C99標準は、「整数が分割されると、 /演算子の結果は、任意の部分的な部分が破棄された代数指数である」と定義しています。そして、「これはしばしば「ゼロへの切り捨て」と呼ばれることが多い」と脚注に追加します。

歴史

歴史的に、言語仕様が責任を負います。

パスカル オペレーターを定義します 使用する / 分割の場合は常にaを返します real (2つの整数を分割するために使用しても)、整数を分割して整数の結果を取得する場合は、 div 代わりにオペレーター。 (Visual Basicには同様の区別があり、 \ 整数結果を返す整数部門のオペレーター。)

Cでは、整数オペランドの1つをにキャストすることにより、同じ区別を行う必要があることが決定されました。 float フローティングポイントの結果が必要な場合。多くのC由来の言語で説明する方法で、整数と浮動点タイプを扱うことが慣習になります。この条約はFortranで発生したのではないかと思います。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top