いつfabsを使用し、いつstd :: absで十分ですか?


100

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

回答:


124

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

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


これはすべてのプラットフォームで当てはまりますか?特に WindowsおよびMac OS X?それとも、少なくともC ++標準では?
数学

3
@brubelsabs:はい。C ++には関数のオーバーロードがあるため、C ++に別個のfabs関数は必要ありません(absは多数の型に対して定義でき、C ++にあります)。また、規格によって保証されています。もちろん、10年以上前の古いコンパイラを探してみたら、それをサポートしていないコンパイラを見つけるかもしれません。
stinky472 2010年

1
それはそれは、WindowsとMac OS Xの句26.5含めまともなコンパイラ、とのすべてのプラットフォーム上の場合だことに加えて、それを言って、C ++標準でありますintCライブラリのバージョン、についてのオーバーロードがありlongfloatdoublelong double。26.2.7項​​では、のオーバーロードも定義していcomplexます。
Mike Seymour 2010年

6
を忘れてstd::そのまま使用したabs場合、コードはWindowsでは期待どおりに動作しますがint、Linuxではバージョンを使用するため、デバッグが非常に難しくなる可能性があります。
Adversus、2015年

すべての数値型」[引用が必要]。int、long、long long、std :: intmax_t、float、double、long doubleが表示されます。短いバージョンやcharバージョン(または署名なしバージョン)は表示されません。
user673679

23

fabsfor doublefloat引数を使用しても問題ありません。これは、誤ってをstd::オフにした場合でもabs、浮動小数点入力の動作が同じになるようにするためです。

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

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


2
それは変だ。あなたの電話はあいまいだったはずです(そしてエラーです)?
Nick

floatにfabsfを使用するべきではありませんか?だから私はそれらが同一であるとは思いません。
Nick

Android NDK g ++に注意してください。また、std :: abs()の代わりにc abs()関数に移行します。ただし、Visual Studio c ++コンパイラでは、absは常にstd :: abs()を指します。
サザントン2015年

@Nick、私はあなたに同意すると思う:私は、オーバーロードが私のためにアラン・チューリングすなわちの動作を取得していないようstd::abs常に(のC-バージョンではなく呼び出されるようだabs呼び出すとき)abs限りとしてusing namespace std;でexplicatedされます始まり。これがコンパイラ固有かどうかはわかりません。
MaviPranav 2016

一致する関数名があるため、@ Nickはエラーではありません。どれが選択されるかは、実装によって定義されます。
パトサンダナ

11

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

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


1

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

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

数週間以来、私はC ++の「既存の問題ではない」に苦労しています。古いC ++プログラムをC ++ 14に更新して、以前よりも多くのテンプレートを使用できるようにしています。多くの場合、同じテンプレートパラメータは、実際の標準のfloat型、複合型、またはクラス型の場合があります。なぜこれまで、ロングダブルは他のタイプよりもいくぶん賢明に振る舞った。すべてが機能しており、以前にmprealを含めていました。次に、デフォルトの浮動小数点型をmprealに設定していて、大量の構文エラーが発生しました。これにより、たとえばabsとsqrtに対して、さまざまな解決策を求めて、何千ものあいまいなオーバーロードが発生しました。一部はオーバーロードされたヘルプ機能を必要としていましたが、テンプレートの外にありました。0.0Lと1.0Lの1000の使用法を、ZeroまたはOneまたはtype_castを使用した正確な定数タイプに個別に置き換える必要がありました-あいまいさのために自動変換定義は不可能です。

5月まで、暗黙的な変換の存在が非常に優れていることがわかりました。しかし、それがないとはるかに簡単になり、他の標準の定数型への安全な明示的なtype_castsを含む型保存定数を持つことになります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.