Есть ли разница между std :: abs и std :: fabs применительно к значениям с плавающей запятой?

Eсть связанный вопрос но я считаю, что это не отвечает на этот вопрос.

Смотря на std::abs а также std::fabs документация они, кажется, ведут себя точно так же. Что касается меня, мне кажется, что std::fabs является предпочтительным, потому что это уменьшает неопределенность с std::abs(int) определение в <cstdlib>(Увидеть нота).

Итак, мой вопрос: помимо std::abs(int) потенциальная неопределенность, есть ли разница между std::abs а также std::fabs применительно к значениям с плавающей запятой?

1

Решение

В стандартном коде, который включал cmath и только звонки std::abs на floats, 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,

2

Другие решения

Есть ли какая-либо разница между std :: abs и std :: fabs применительно к значениям с плавающей запятой?

Нет там нет. Также нет разницы для целочисленных типов.

Идиоматично использовать std::abs() потому что это наиболее близко к обычно используемой математической номенклатуре.

1

По вопросам рекламы [email protected]