web-dev-qa-db-ja.com

いつfabを使用しますか?std :: absを使用するのに十分なのはいつですか?

math.hを使用する場合、absfabsは異なる動作をすると仮定します。しかし、cmathstd::absだけを使用する場合、std::fabsまたはfabsを使用する必要がありますか?または、これは定義されていませんか?

94
math

C++では、std::abs;を使用するだけで十分です。すべての数値型でオーバーロードされます。

Cでは、absは整数でのみ機能し、浮動小数点値にはfabsが必要です。これらは(すべてのCライブラリと一緒に)C++で使用できますが、使用する必要はありません。

120
Mike Seymour

fabsおよびdouble引数にfloatを使用しても大丈夫です。これは、absからstd::を誤って削除しても、浮動小数点入力の動作が変わらないことを保証するためです。

std::absの代わりにabsを使用する私自身のミスのため、この非常に問題をデバッグするのに10分かかりました。私はusing namespace std;std::absを推論すると仮定したが、そうではなく、代わりにCバージョンを使用していた。

とにかく、意図を明確に文書化する方法として、浮動小数点入力にfabsの代わりにabsを使用するのが良いと思います。

22
Alan Turing

浮動小数点入力に明示的に_std::fabs_を推奨する理由がもう1つあります。

<cmath>を含めるのを忘れた場合、std::abs(my_float_num)std::abs(int)ではなくstd::abs(float)にできます。気づきにくいです。

10
Kenichi Hidai

「abs」と「fabs」は、あいまいなオーバーロードメッセージなしで変換できる場合にのみ、C++ float型で同一です。

私はg ++(g ++-7)を使用しています。テンプレートの使用と一緒に、特にmprealを使用する場合、ハードな「あいまいなオーバーロード」メッセージが表示される場合があります-abs(static_cast<T>(x))は常にそれを解決するとは限りません。 absがあいまいな場合、fabsが期待どおりに機能する可能性があります。 sqrtの場合、このような単純なエスケープは見つかりませんでした。

数週間以来、「既存の問題ではない」C++に苦労しています。古いC++プログラムをC++ 14に更新して、以前よりもテンプレートの使用を改善しました。多くの場合、同じテンプレートパラメータは、実際の標準のfloat型、complex型、またはクラス型です。なぜこれまで、ロングダブルは他のタイプよりも多少賢明でした。すべてが機能しており、以前はmprealを含めていました。その後、デフォルトのフロートタイプをmprealに設定すると、大量の構文エラーが発生しました。これにより、数千のあいまいなオーバーロードが発生しました。 absとsqrtの場合、さまざまなソリューションを求めて泣きます。オーバーロードされたヘルプ機能が必要なものもありましたが、テンプレートの外部にありました。ゼロまたはワンまたはtype_castを使用して、0.0Lおよび1.0Lの千回の使用を正確な定数型で個別に置き換える必要がありました-あいまいさのために自動変換定義は不可能です。

5月まで、私は既存の暗黙的な変換が非常に素晴らしいことを発見しました。しかし、もっと簡単なのは、何も持たず、安全な明示的なtype_castsを持つtypesave定数を他の標準定数型に持たせることです。

1
BS3