Eсть связанный вопрос но я считаю, что это не отвечает на этот вопрос.
Смотря на std::abs
а также std::fabs
документация они, кажется, ведут себя точно так же. Что касается меня, мне кажется, что std::fabs
является предпочтительным, потому что это уменьшает неопределенность с std::abs(int)
определение в <cstdlib>
(Увидеть нота).
Итак, мой вопрос: помимо std::abs(int)
потенциальная неопределенность, есть ли разница между std::abs
а также std::fabs
применительно к значениям с плавающей запятой?
В стандартном коде, который включал cmath
и только звонки std::abs
на float
s, double
с и long double
с, нет никакой разницы. Однако полезно взглянуть на типы, возвращаемые std::abs
на различные типы, когда вы вызываете его с различными наборами заголовочных файлов.
В моей системе std::abs(-42)
это double
если я включил cmath
но нет cstdlib
, int
если я включил cstdlib
и выдает ошибку компиляции, если я не включил ни того, ни другого. Наоборот, std::abs(-42.0)
выдает ошибку компиляции (неоднозначную перегрузку), если я включил cstdlib
но я не включил cmath
или другая ошибка компиляции (никогда не слышал о std::abs
) если я не включил ни того, ни другого
На моей платформе std::abs('x')
дает мне double
если я включил cmath
или int
если я включил cstdlib
но нет cmath
, Похоже на short int
, Подпись не имеет значения.
На моей платформе complex
заголовок, очевидно, вызывает как интегральные, так и перегрузки с плавающей точкой std::abs
быть объявленным. Я не уверен, что это необходимо; возможно, вы найдете разумную платформу, на которой std::abs(1e222)
возвращает бесконечность с неверным набором стандартных заголовков.
Обычное последствие «вы забыли заголовок в вашей программе» — ошибка компиляции с жалобой на неопределенный символ, а не скрытое изменение поведения. С std::abs
Однако результат может быть std::abs(42)
возвращая double
если ты забыл cstdlib
или же std::abs('x')
возвращая int
если ты не сделал. (Или, возможно, вы ожидали std::abs
чтобы дать вам целостный тип, когда вы передаете его short
? Затем, предполагая, что мой компилятор правильно продвинулся и разрешил перегрузку, вам лучше убедиться, что вы не включили cmath
.)
Я также провел слишком много времени в прошлом, пытаясь понять, почему код, как double precise_sine = std::sin(myfloat)
дает неточные результаты. Поскольку я не люблю тратить свое время на подобные сюрпризы, я стараюсь избегать перегруженных вариантов стандартных функций C в namespace std
, То есть я использую ::fabs
когда я хочу double
быть возвращенным, ::fabsf
когда я хочу float
и ::fabsl
когда я хочу long double
из. Аналогично для ::abs
когда я хочу int
, ::absl
когда я хочу long
, а также ::absll
когда я хочу long long
,
Есть ли какая-либо разница между std :: abs и std :: fabs применительно к значениям с плавающей запятой?
Нет там нет. Также нет разницы для целочисленных типов.
Идиоматично использовать std::abs()
потому что это наиболее близко к обычно используемой математической номенклатуре.