Я предполагаю, что abs
и fabs
при использовании ведут себя иначе math.h
. Но когда я использую только cmath
и std::abs
, нужно ли мне использовать std::fabs
или fabs
? Или это не определено?
100
В C ++ всегда достаточно использовать std::abs
; он перегружен для всех числовых типов.
В C abs
работает только с целыми числами, а вам нужны fabs
значения с плавающей запятой. Они доступны в C ++ (вместе со всей библиотекой C), но в их использовании нет необходимости.
int
версии из библиотеки C, есть перегруженные дляlong
,float
,double
иlong double
. В пункте 26.2.7 также определяется перегрузка дляcomplex
.std::
и просто используетеabs
, ваш код будет работать в Windows, как ожидалось, но будет использоватьint
версию в Linux, что может быть невероятно сложно отладить.По-прежнему можно использовать аргументы
fabs
fordouble
иfloat
. Я предпочитаю это , потому что это гарантирует , что , если я случайно обиратьstd::
выключитьabs
, что поведение остается неизменным с плавающей точкой входа.Я просто потратил 10 минут на отладку этой самой проблемы из-за моей собственной ошибки в использовании
abs
вместоstd::abs
. Я предполагал, что этоusing namespace std;
будет вывод,std::abs
но этого не произошло, и вместо этого использовал версию C.В любом случае, я считаю, что лучше использовать
fabs
вместоabs
ввода с плавающей запятой как способ четко задокументировать свое намерение.источник
std::abs
всегда вызывается перегруженный (а не C-версияabs
) при вызове,abs
еслиusing namespace std;
это объяснено в начало. Я не знаю, зависит ли это от компилятора.Есть еще одна причина
std::fabs
явно рекомендовать ввод с плавающей запятой.Если вы забыли включить <CMATH>, ваш
std::abs(my_float_num)
может бытьstd::abs(int)
вместоstd::abs(float)
. Это сложно заметить.источник
«abs» и «fabs» идентичны только для типов с плавающей запятой C ++, когда они могут быть переведены без неоднозначных сообщений о перегрузке.
Я использую g ++ (g ++ - 7). Вместе с использованием шаблонов и особенно при использовании mpreal бывают случаи с жесткими сообщениями о "неоднозначной перегрузке" -
abs(static_cast<T>(x))
не всегда это решает. Когда abs неоднозначен, есть вероятность, что fabs работает должным образом. Для sqrt я не нашел такого простого выхода.С недели я трудно бороться на C ++ «не существующих проблем». Я обновляю старую программу C ++ до C ++ 14 для более широкого и лучшего использования шаблонов, чем это было возможно раньше. Часто один и тот же параметр шаблона может быть любым стандартным типом с плавающей запятой, сложным типом или типом класса. Да и вообще, длинный дубль действовал несколько разумнее, чем другие типы. Все работало, и раньше я включил mpreal. Затем я установил тип float по умолчанию на mpreal и получил массу синтаксических ошибок. Это дало тысячи неоднозначных перегрузок, например, для abs и sqrt, требующих различных решений. Некоторым требовались перегруженные справочные функции, но не по шаблону. Пришлось заменить по отдельности тысячу использований 0.0L и 1.0L точным типом константы с использованием Zero или One или type_cast - автоматическое определение преобразования невозможно из-за двусмысленности.
До мая я находил очень приятным наличие неявных преобразований. Но гораздо проще было бы без них и иметь константы с сохранением типов с безопасным явным преобразованием типа в любой другой стандартный тип константы.
источник