2010-06-25 4 views

Antwort

105

In C++ ist es immer ausreichend zu verwenden std::abs; es ist für alle numerischen Typen überladen.

In C funktioniert abs nur für Ganzzahlen und Sie benötigen fabs für Fließkommawerte. Diese sind in C++ (zusammen mit allen C-Bibliotheken) verfügbar, müssen aber nicht verwendet werden.

+0

Ist dies auf jeder Plattform der Fall? Esp. Windows und Mac OS X? Oder ist es zumindest im C++ - Standard? – math

+2

@rubelsab: ja. Es gibt keine Notwendigkeit für eine separate fabs-Funktion in C++, da C++ überladen ist (abs kann für zahlreiche Typen definiert werden und ist in C++). Es ist auch durch den Standard garantiert. Natürlich, wenn Sie nach einem veralteten Compiler suchen, der älter als 10 Jahre ist, finden Sie vielleicht einen, der ihn nicht unterstützt. – stinky472

+1

Es ist im C++ Standard, also ist es auf jeder Plattform mit einem ordentlichen Compiler, einschließlich Windows und Mac OS X der Fall. Abschnitt 26.5 sagt, dass zusätzlich zur 'int'-Version aus der C-Bibliothek Überladungen für' long vorhanden sind ',' float', 'double' und' long double'. Abschnitt 26.2.7 definiert auch eine Überladung für "komplex". –

21

Es ist immer noch in Ordnung, fabs für double und float Argumente zu verwenden. Ich bevorzuge das, weil es sicherstellt, dass, wenn ich versehentlich die std:: von der abs strip, dass das Verhalten für Fließkomma-Eingänge gleich bleibt.

Ich verbrachte gerade 10 Minuten Debugging dieses sehr Problem, aufgrund meines eigenen Fehlers der Verwendung abs anstelle von std::abs. Ich nahm an, dass die using namespace std; würde std::abs ableiten, aber es tat nicht, und stattdessen wurde die C-Version verwendet.

Wie auch immer, ich glaube, es ist gut zu verwenden fabs anstelle von abs für Fließkomma-Eingänge als eine Möglichkeit, Ihre Absicht klar zu dokumentieren.

+2

Das ist komisch. Ihr Anruf sollte mehrdeutig sein (und somit ein Fehler) oder? – Nick

+0

Sollten Sie fabsf nicht für Float verwenden? Also ich glaube nicht, dass sie identisch sind. – Nick

+0

Hüten Sie sich vor Android NDK g ++, es ersetzt auch die Funktion abs() statt std :: abs(). In Visual Studio C++ - Compiler zeigt jedoch ABS immer auf std :: abs(). – southerton

7

Es gibt einen weiteren Grund, std::fabs explizit für Gleitkomma-Eingänge zu empfehlen.

Wenn Sie einschließen vergessen <cmath>, Ihre std::abs(my_float_num)std::abs(int) statt std::abs(float) sein. Es ist schwer zu bemerken.

1

"abs" und "fabs" sind nur für C++ - Float-Typen identisch, wenn sie ohne mehrdeutige Überladungsnachrichten übersetzt werden können.

Ich benutze g ++ (g ++ - 7). Zusammen mit Template-Verwendung und vor allem bei der Verwendung von Mpreal gibt es Fälle mit schweren "mehrdeutigen Überladung" Nachrichten - abs(static_cast<T>(x)) löst das nicht immer. Wenn abs mehrdeutig ist, gibt es Chancen, dass Fabs wie erwartet funktioniert. Für sqrt fand ich keine so einfache Flucht.

Seit Wochen kämpfe ich hart auf C++ "nicht vorhandene Probleme". Ich aktualisiere ein altes C++ - Programm nach C++ 14 für mehr und bessere Vorlagennutzung als zuvor möglich. Häufig kann derselbe Template-Parameter ein beliebiger Standard-Float- oder -Komplextyp oder ein Klassentyp sein. Warum auch immer, das lange Doppelte wirkte etwas vernünftiger als andere Typen. Alles funktionierte, und ich hatte mpreal vorher eingeschlossen. Dann habe ich meinen Standard-Float-Typ auf Mpreal gesetzt und eine Flut von Syntaxfehlern bekommen. Das gab Tausende von mehrdeutigen Überlastungen, z.B. für abs und sqrt, weinen für verschiedene lösungen. Einige benötigten überladene Hilfefunktionen, aber außerhalb einer Vorlage. Er musste einzeln tausende Anwendungen von 0.0L und 1.0L durch den genauen konstanten Typ ersetzen, indem er Zero oder One oder einen type_cast verwendete - die automatische Umwandlung ist aufgrund von Unklarheiten unmöglich.

Bis Mai fand ich die vorhandenen impliziten Konvertierungen sehr nett. Aber viel einfacher wäre es ohne und typesave Konstanten mit sicheren expliziten type_casts zu jedem anderen Standardkonstanten-Typ zu haben.