2011-01-26 15 views
3

cプログラミングでは、以下の式の変数k、X、Y、nを使用します(exp()は数学定数eを()に上げ、pi = 3.14159 .. 、およびj = sqrt(-1))、これらの変数はすべて64b倍精度浮動小数点数(Xは複素数)として宣言され、出力の結果もこのデータ型になります。私は、よりインテリジェントメモリを管理しようとする場合、c言語のデータ型算術規則

output = k * exp(2*pi*j*X*Y/n) 

今、私は

K、Y、およびnは、符号なしlong int型(0〜4294967295)を32ビットすること、および

をしたいのですが

pi、j、およびXは32ビット浮動小数点です。

私の質問は、結果がデータ型float(うまくいけば)かunsigned long intかどうかです。つまり、C言語には浮動小数点数と整数を乗算して結果をfloatとしてインテリジェントに処理するいくつかのデフォルトルールがありますか、またはタイプキャストなどを使って手動で管理する必要がありますか?私がこのような操作で心配する必要があるものがあるのか​​、それとも私がCの中に残して舞台裏ですべてを知的に行うことができるのか不思議です。

+3

これは非常に悪い考え方です。整数を浮動小数点数と混合すると、パフォーマンスが大幅に低下します。可能であればそれを試してください。 – ruslik

+0

なぜ複合型を使用しないのですか? – Artefacto

答えて

5

これは一種の醜いことができます。コンパイラは、オペランドのオペランドの型を調べて、より大きい型に昇格します(たとえば、1つがintで、もう1つがdoubleの場合、intdoubleに変換してから操作します) )。

あなたのケースでは、予期しない結果が生じることがあります。今あなたは持っています:2*pi*j*X*Y/n。演算子は左から右にグループ化されているので、((((2*pi)*j)*X)*Y)/nに相当します。この場合、おそらくうまくいくでしょう - 「最初の」演算のオペランドの1つは浮動小数点数なので、他のすべてのオペランドは必要に応じて浮動小数点数に変換されます。ただし、オペランドを並べ替えると(通常の数学では同等に見えますが)、結果はまったく異なる場合があります。たとえば、2*Y/n*pi*j*Xに並べ替えた場合、の整数は、の演算を使用して行われます。2,Y、およびnはすべて整数です。これは、除算が整数で行われ、整数結果が得られ、の後に整数結果が得られたの場合には、その整数は乗算のためにfloatに変換されてpiになります。

ボトムライン:大きな配列のようなものを扱っていない限り、より小さい型に変換するとメモリが大幅に節約される可能性が高いため、通常は同じ型のすべてのオペランドを保持するほうがずっと優れています可能。とにかく、この場合、「メモリをインテリジェントに管理する」という試みは、とにかくうまくいっていない可能性があることにも気づくでしょう。典型的な現在のマシンでは、long intfloatは両方とも32ビットなので、いずれの場合でもメモリの量。また、expdoubleをオペランドとしているので、残りの計算でfloatを実行しても、とにかくdoubleに昇格されます。また、intからfloat(およびそれ以降)のコンバージョンはかなり遅くなる可能性があります。

実際に半ダースの変数しか扱っていないのであれば、ほとんどの場合、それらをdoubleのままにしておき、それを実行するのが最も良いでしょう。 floatlongの組み合わせに変換すると約14バイトのデータストレージが節約されますが、int,floatdoubleの間のすべてのコンバージョンを適切なタイミングで処理するための14バイトの追加命令が追加されますとにかく多量のメモリを使用するより遅いコードを使っています。

+0

非常に興味深い回答、ありがとうございます。そして私はintとfloatを慎重に選択して物事を助けていると思った。それで、64ビットの精度ですべてを2倍に保つか、すべてが32ビットの精度で浮動することがコンセンサスであるようです。いいね? – ggkmath

+0

@gkmath:はい、私はたぶんそれらをダブルスのままにしておきます。 –

+0

ありがとう、ジェリー、そんなに! – ggkmath

8

浮動小数点数と整数で算術演算を行う場合、常に浮動小数点数に変換します。それは言うことです:

  • フロート*フロート=フロート
  • フロート* int型=フロート
  • int型*フロート=フロート
  • int型* int型= INT

あなただけ受け取ることになりますすべての値がintの場合は "整数演算"。

+0

この回答は少し誤解を招くものです。 "float"を "double"に置き換える必要があります。 Cに浮かべるような宣伝はありません。 –

+1

あります。これらを「通常の算術変換」と呼びます。この投稿のintはdoubleではなくfloatに変換されます。 ISO 9899:1999 6.3.1.8を参照してください。 – Lundin

2

山車上でこのようなC言語の作品では「通常の算術変換」:

  • 両方のオペランドが同じ型である場合には、すべてが正常です。
  • 一方がdoubleの場合、もう一方はdoubleに変換されます。
  • それ以外の場合はfloat、もう一方はfloatに変換されます。
  • それ以外の場合は、整数乗算のさまざまなルールが適用されます。

数値定数 "1"はintと見なされます。 数値定数 "1.0"はdoubleと見なされます。 数値定数 "1.0f"はfloatと見なされます。

関連する問題