abs
とfabs
の違いをチェックしましたpython here
私が理解しているように、速度と渡されたタイプに関していくつかの違いがありますが、私の質問はV.Sのネイティブc ++に関連しています。
V.S.についてVisual Studio 2013 (v120)
で次のことを試しました:
_float f1= abs(-9.2); // f = 9.2
float f2= fabs(-9); // Compile error [*]
_
fabs(-9)
はコンパイラエラーを発生させますが、次のことを試みたとき:
_double i = -9;
float f2= fabs(i); // This will work fine
_
fabs(-9)
にはdoubleが必要であり、コンパイラは-9を-9.0に変換できなかったため、コンパイルされないことを最初のコードから理解していますが、2番目のコードではコンパイラは_i=-9
_を変換しますコンパイル時に_i=-9.0
_に変更されるため、fabs(i)
は正常に動作します。
より良い説明はありますか?
もう1つの理由は、コンパイラがfabs(-9)
を受け入れず、C#のようにint値を自動的にdoubleに変換できない理由です。
_[*]:
Error: more than one instance of overloaded function "fabs" matches the argument list:
function "fabs(double _X)"
function "fabs(float _X)"
function "fabs(long double _X)"
argument types are: (int)
_
C++では、_std::abs
_は符号付き整数型と浮動小数点型の両方でオーバーロードされます。 _std::fabs
_は浮動小数点型のみを扱います(C++ 11より前)。 _std::
_は重要であり、レガシーの理由で一般的に使用可能なC関数_::abs
_はint
!のみを処理することに注意してください。
の問題
_float f2= fabs(-9);
_
int
(_-9
_のタイプ)からdouble
への変換がないことではなく、コンパイラーはどの変換を選択するかを知らない(int
-> float
、double
、_long double
_)これら3つのそれぞれに_std::fabs
_があるため。回避策は、int
-> double
変換を使用するようコンパイラーに明示的に指示するため、あいまいさがなくなります。
C++ 11は、abs
に変換された整数型のdouble
を返すdouble fabs( Integral arg );
を追加することでこれを解決します。どうやら、このオーバーロードは、libstdc ++およびlibc ++を使用したC++ 98モードでも使用できます。
一般に、_std::abs
_を使用するだけで、正しいことを行います。 ( 興味深い落とし穴@ Shafik Yaghmour によって指摘されています。C++では、符号なし整数型はおかしなことをします。)
私のVisual C++ 2008は、long double fabs(long double)
、float fabs(float)
、またはdouble fabs(double)
のどれを選択するかを知りませんでした。
ステートメント_double i = -9;
_では、double
の型がi
であるため、コンパイラーは_-9
_をdouble
に変換する必要があることを認識します。
abs()
は_stdlib.h
_で宣言され、int
値を処理します。
fabs()
は_math.h
_で宣言され、double
値を処理します。
C++ 11では、abs()
のみを使用すると非常に危険です。
#include <iostream>
#include <cmath>
int main() {
std::cout << abs(-2.5) << std::endl;
return 0;
}
このプログラムは、結果として2
を出力します。 ( ライブで見る )
常にstd::abs()
を使用します。
#include <iostream>
#include <cmath>
int main() {
std::cout << std::abs(-2.5) << std::endl;
return 0;
}
このプログラムは2.5
を出力します。
using namespace std;
で予期しない結果を避けることができますが、一般的に悪い習慣と見なされているため、using
ディレクティブを検索してabs()
がint
を意味するかどうかを知る必要があるため、オーバーロードまたはdouble
オーバーロード。