web-dev-qa-db-ja.com

int対floorにキャスト

これらの間に違いはありますか:

float foo1 = (int)(bar / 3.0);
float foo2 = floor(bar / 3.0);

私が理解しているように、両方のケースは同じ結果になります。コンパイルされたコードに違いはありますか?

107
OgreSwamp

Intにキャストすると、ゼロに向かって切り捨てられます。 floor()は負の無限大に向かって切り捨てます。 barが負の場合、これにより異なる値が得られます。

170
James Curran

前に述べたように、正の数の場合は同じですが、負の数の場合は異なります。規則は、intは0に向かって丸め、floorは負の無限大に向かって丸めることです。

floor(4.5) = (int)4.5 = 4
floor(-4.5) = -5 
(int)(-4.5) = -4

とはいえ、実行時間にも違いがあります。私のシステムでは、キャスティングがフロアより少なくとも3倍速いと時間を計りました。

負の数値を含む限られた範囲の値のフロア演算を必要とするコードがあります。また、非常に効率的である必要があるため、次の関数を使用します。

int int_floor(double x) 
{ 
    return (int)(x+100000) - 100000; 
}

もちろん、これはxの非常に大きな値(いくつかのオーバーフローの問題に遭遇します)および-100000未満の負の値などでは失敗します。私たちのアプリケーションのために。一粒の塩でそれを取り、システムなどでテストしますが、私見を検討する価値があります。

24
brice rebsamen

SO 101、人々があなたの質問に答えた後にあなたの質問を変更せず、代わりに新しい質問を書いてください。

なぜ同じ結果になると思いますか?

float foo = (int)(bar / 3.0) //will create an integer then assign it to a float

float foo = fabs(bar / 3.0 ) //will do the absolute value of a float division

bar = 1.0

foo1 = 0;
foo2 = 0.33333...
9
Anders

編集:質問はfabs()floor()の混同により変更された可能性があるため。

元の質問の例の行を考えます:

1.  float foo = (int)(bar / 3.0);

2.  float foo = fabs(bar / 3.0);

違いは、barが負の場合、結果は最初は負で、2番目は正になるということです。最初は整数に切り捨てられ、2番目は小数部分を含む完全な10進値を返します。

4
Amardeep AC9MF

はい。 fabsは引数の絶対値を返し、intにキャストすると除算が切り捨てられる(最も近いintまで)ので、結果はほとんど常に異なります。

3
warrenm

主に2つの違いがあります。

  1. 他の人が指摘したように、整数へのキャストはゼロに向かって切り捨てられますが、floor()は常に負の無限大に向かって切り捨てられます。これは、負のオペランドに対する異なる動作です。

  2. 誰も(まだ)別の違いを指摘していないようです-引数がMAX_INT+1以上(または-MAX_INT-1以下)の場合、intにキャストすると、ドロップされている最上位ビット(おそらくC)または未定義の動作(C++および場合によってはC)。たとえば、intが32ビットの場合、符号ビットと31ビットのデータのみがあります。したがって、サイズの大きいdoubleでこれを使用すると、意図しない結果が生成されます。

2
abligh

_(int) x_は、xの整数部分を保持するための要求です(ここでは丸めはありません)

fabs(x) = | x |そのため_>= 0_;

例:_(int) -3.5_は_-3_を返します。 fabs(-3.5)は_3.5_を返します。

一般に、すべてのxに対してfabs (x) >= xです。

x >= (int) x if _x >= 0_

x < (int) x if _x < 0_

0
Paul Hoang