整数の除算が整数になるのはなぜですか?

プログラミング入門で、2つの整数を除算すると、常に整数が得られることを学びました。この問題を解決するには、これらの整数の少なくとも1つをfloatにします。

結果を10進数にしたいことをコンパイラが理解しないのはなぜですか?

コメント

  • 代わりに結果を整数にしたい場合があります。違いはどのようにわかりますか?
  • C ++標準ではそう言われているためです。
  • @soandos:PascalとPythonの両方の方法:個別の整数除算演算子がありますが、標準の除算演算子は常に数学的に正しい結果を返します(または、ペダンティックの場合は、与えられたとおりに正しい結果を返します。 FP数学の制限。)
  • 結果を10進数にしたいことをコンパイラはどのようにして知るのでしょうか?整数が必要な正当な理由があります。
  • @soandos Pythonでは、//は整数除算演算子であり、#は1行のコメントです。Pascalでは、整数除算演算子はキーワード

。どちらもそれぞれの言語で非常にうまく機能しますges。 Cはおそらく可能な限り最悪のことをします:任意のコンテキストに基づいて2つの完全に異なることを実行できる1つの演算子。

回答

結果を10進数にしたいことをコンパイラが理解しないのはなぜですか?

C ++コンパイラは、C ++標準で規定されている明確に定義された決定論的ルールに従っています。C++標準には標準委員会はそのようにすることを決定しました。

整数演算は浮動小数点数になるという標準を作成することもできますし、そうするのは残りの場合。ただし、複雑さが増します。結果が何であるかを事前に知る必要があるか、常に浮動小数点数が得られる場合は整数に変換し直す必要があります。整数が必要な場合があります。

C ++のコア哲学の1つは、「使用しないものに対してはお金を払わない」です。 。」整数と浮動小数点数の混合の複雑さを実際に望んでいる場合(および追加のCPU命令とメモリアクセスには 1 が必要です)、質問で述べたように型キャストを実行します。それ以外の場合は、標準の整数計算に固執します。

最後に、整数変数と浮動小数点変数を混在させると、精度が低下し、以下で説明するように誤った結果になる場合があります。これが必要な場合は、それを支払います。それ以外の場合、標準では、コンパイラーはデータ型を混合するための厳密なルールセットに固執するように定められています。これは明確に定義された動作です。C++開発者として、これを標準で調べて、どのように機能するかを確認できます。


実行しようとしていることを実行するには、基本的に3つの方法があります。それぞれに長所と短所があります。

  • 整数演算:これにより、除算中に結果が切り捨てられます。小数部分が必要な場合は、除算して余りを取得し、小数部分を除数で割った余りとして扱うことで、個別に処理する必要があります。これは操作が少し複雑で、調整する変数が多くなります。

  • 浮動小数点演算:これは通常、小さい値に対して正しい(十分な)結果を生成しますが、特に指数が増加すると、精度と丸めでエラーが発生しやすくなります。大きな数を小さな数で割ると、数値の目盛りが互いにうまく機能しないため、アンダーフローが発生したり、単に間違った結果が得られたりする可能性があります。

  • あなた自身の数学をしてください。 拡張精度の10進数と有理数を処理するクラスがあります。これらは通常、組み込み型の計算よりも低速ですが、一般的にはかなり高速で、任意精度の計算を提供します。丸めやその他の問題は、IEEEフロートの場合のように自動ではありませんが、より詳細な制御と確実により高い精度が得られます。

ここで重要なのは、問題のドメインに基づいて選択することです。 。数値を表す3つの方法にはすべて、それぞれ長所と短所があります。ループカウンターを使用していますか?整数型を選択してください。 3D空間で場所を表現しますか?おそらくフロートのグループ。お金を追跡したいですか?固定10進型を使用します。


1 最も一般的なCPUアーキテクチャ(例: x86-64 )には、整数や浮動小数点などのさまざまなレジスタタイプで動作する個別の命令セットに加えて、整数、浮動小数点、およびそれらのさまざまな表現(符号付きと符号なし、浮動小数点と二重)の間で変換する追加の命令があります。これらの操作の中には、メモリアクセスを伴うものもあります。値を変換してメモリ(その変数)に格納します。 CPUレベルでの計算は、「整数イン、フロートアウト」ほど単純ではありません。「2つの整数を追加することは非常に簡単な操作であり、おそらく1つの命令ですが、データ型を混在させると複雑さが増す可能性があります。

コメント

  • C ++標準では、その動作がそうあるべきであると規定されているとおっしゃっています。なぜですか?'言いやすくなるのではないでしょうか、"整数を均等に分割できないと、浮動小数点数になります。他の分割は公正なゲームです。"
  • @ moonman239私の編集を参照してください。
  • @ moonman239コンパイラの作成者向けではありません。一般的に使用されるCPUアーキテクチャの多くは、2つの整数で除算するように求められると整数の結果を提供します。整数以外の結果のチェックを実装してから、より遅い浮動小数点を使用するように切り替える必要があります。あるいは、デフォルトで浮動小数点除算に設定され、高速な計算が必要な人、正確な計算が必要な人、Cに慣れている人の興味を失った可能性があります。 '既存のコードとの互換性が失われるため、オプションではありません。
  • これを代替手段として提唱するのではなく、静的型の式を作成します。オペランドの実行時の値に依存します' C ++ 'の静的型システムでは機能しません。
  • @ moonman239:オペランドのに応じて異なる型を生成する演算を行うことはまったくの狂気です。

回答

これは、ハードウェアの進化によるものです。コンピュータの初期の頃、すべてのマシンに浮動小数点ユニットがあるわけではなく、ハードウェアは単に浮動小数点数の概念を理解できませんでした。もちろん、浮動小数点数はソフトウェアの抽象化として実装できますが、それには重大な欠点があります。これらのマシンのすべての演算は、デフォルトで純粋な整数演算である必要がありました。

そして今日でも、CPU内の整数演算ユニットと浮動小数点演算ユニットは明確に区別されています。それらのオペランドは、最初は別々のレジスタファイルに格納され、整数単位は2つの整数引数を取り、最終的に整数レジスタになる整数結果を生成するように配線されています。一部のCPUでは、整数値をメモリに格納してから、浮動小数点レジスタにリロードしてから、浮動小数点数に再コード化してから、浮動小数点除算を実行する必要があります。

そのため、言語の最初の段階でC開発者が下した決定(C ++は単にこの動作を継承した)が唯一の適切な決定であり、今日でも価値があります。浮動小数点演算が必要な場合は、使用できます。必要がない場合は、必要ありません。

コメント

  • に存在した制約のほとんどが、 C ++標準の作成は、今日ではかなり時代遅れになっています。例:"使用しないものに対して料金を支払うことはありません。"現在、ハードウェアは当然のことと見なされており、すべてのユーザーが望んでいるのは実行!
  • @ mahen23すべてのユーザーがこのように考えるわけではありません。私は、プログラムが何千ものCPUコアで並行して実行される分野で働いています。この分野では、投資と電力消費の両方の観点から、効率はお金です。 Javaのような言語は、C ++がそうであるのに対し、その分野でのチャンスの幽霊に耐えることはできません。
  • @ mahen23いいえ、そうではありません' t-またはそれ以上に、デスクトップ以上の現在のCPUアーキテクチャを確認する場合のみです。 '浮動小数点演算をサポートしていない、または部分的にしかサポートしていない組み込みシステムはまだたくさんあります。CおよびC ++は、可能な限り最も効率的な実装を提供するために、引き続きそれらをサポートします。アセンブラを使用します。ところで、Pythonのようなさらに高レベルの言語は整数演算とFP演算を区別します-10 / 3を試してください。

回答

10/2と整数を使用すると、正確に5-正解が得られます。

浮動小数点演算を使用すると、10/2 が正解になる可能性があります回答*。

言い換えると、現在のハードウェアでは浮動小数点数を「完全」にすることは不可能です。正しいのは整数の計算だけです。残念ながら、小数点以下の桁数はできませんが、簡単な作業があります。

たとえば、4/3の代わりに、(4 * 1000)/(3 * 1000)== 1333を実行します。ユーザーに回答を表示するときにソフトウェアで。を描画するだけです(1.333)。これにより、小数点以下の桁数が正しくないのではなく、正確な答えが得られます。

浮動小数点演算エラーは、合計して重大なエラーを引き起こす可能性があります。重要なもの(財務など)は整数演算を使用します。 。

* 10/2の例は、浮動小数点演算で実際に正しくなります。しかし、あなたはそれに頼ることができません、他の多くの数字は間違った結果を与えます…詳細については、以下をお読みください。 http://http.cs.berkeley.edu/~wkahan/ieee754status/ieee754.ps 要点は、浮動小数点が常に精度に依存することはできないということです。関与

コメント

  • IEEE 754準拠の浮動小数点実装では、10/2の正確な結果が得られます。実際、正確な結果が得られます。オペランドと結果を正確に表すことができ、「十分に小さい」整数を表すことができるという条件で、整数の結果を持つ整数のオペランドのみを含む操作の結果。
  • @ 5gon12eder there 'は、選択を制限する必要はありません。'は、複雑な問題を簡単な用語で説明しようとしているだけです。整数以外の値をサポートすることの全体的なポイントは、小数点以下の桁数(これは、整数を使用して、すべてに必要な小数点以下の桁数を掛けるだけで実行できます。

回答

技術的には完全には正しくありませんが、 C ++は今でもCのスーパーセットと見なされており、それに触発されてそのプロパティの一部を流用しました。整数除算はその1つです。

Cは主に効率的かつ高速に設計されており、整数は一般的に整数型はハードウェアに関連付けられているため、浮動小数点よりもはるかに高速ですが、浮動小数点を計算する必要があります。

/オペランドが2つの整数を受信する場合、1つは左側と右側の1つでは、除算すらできない場合があります。結果は、単純な加算とループを使用して計算され、右側のオペランドが左側のオペランドに何回収まるかを尋ねます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です