Сравнение абсолютных целочисленных значений и квадратов.Это эквивалентно? - PullRequest
0 голосов
/ 03 марта 2019

Существует стандартный способ сравнения абсолютных значений двух целых чисел:

if (std::abs(a) > std::abs(b))
{
   // code
}

Иногда встречается другой способ сравнения абсолютных значений на основе возведения в квадрат значений:

if (a * a > b * b)
{
   // code
}

Естьэти методы эквивалентны?Есть ли разница в производительности этих методов?Какой метод вы бы предпочли?

Ответы [ 3 ]

0 голосов
/ 03 марта 2019

Оба значения эквивалентны, только если числа маленькие .Например, если вы используете 32-разрядный тип int, то a * a будет переполняться вокруг a = 50000, а a * a> b * b даст совершенно неправильные ответы.

Производительность абсолютно не интересна.Вы находитесь на территории наносекундных сбережений здесь.Я предпочитаю код, который не выходит из строя без каких-либо серьезных причин, поэтому вам следует сравнивать абсолютные значения.Также очевидно, что описание вашей проблемы.

0 голосов
/ 04 марта 2019

Пока целочисленный продукт не переполнится, оба метода будут вести себя одинаково.Я бы предпочел использовать std::abs(), потому что это более четко указывает мои намерения - сравнить величину двух чисел.Если я использую продукт a * a, любые другие сопровождающие, которые читают по коду, зададутся вопросом, что означает a * a.

Хотя за пределами буквального вопроса я считаю важным подчеркнуть, что эти два метода расходятсянамного быстрее для нецелых типов.Что касается плавающей запятой, вы очень быстро столкнетесь с ошибками округления, что приведет к немного отличающимся сравнениям, которые иногда могут дать неправильный результат (можно утверждать, что вы не должны делать прямые сравнения с плавающей запятой в любом случае, а вместо этого ограничивать диапазон, новсе еще).

Более тонко, сравнение значений complex таким образом будет некорректным.Типичное вычисление абсолютного значения для комплексного числа a + bi составляет sqrt(a^2 + b^2), где ^ обозначает возведение в степень.Однако (a + bi)^2 даст a^2-b^2 + 2abi, что не может быть равным когда-либо для ненулевых a и b.

0 голосов
/ 03 марта 2019

Абсолютное значение числа возвращает его противоположность, если оно меньше 0, и само, если оно больше 0.

Квадрат числа всегда даст вам положительный результат, поэтому сравнение квадратов целых чисел такое же, как сравнениеих абсолютные значения.Хотя это может отличаться от плавающих чисел.

Короче говоря, лучше использовать std::abs для удобства чтения и избежать возникновения противоречий при работе с плавающими

EDIT:

Вы можете использовать этот класс Timer для сравнения выполнениявремя.Просто объявите экземпляр этого класса в начале функции, которую вы хотите протестировать.

#include <ctime>
#include <chrono>
class Timer
{
  private:
    std::chrono::time_point<std::chrono::steady_clock> start;
    std::chrono::time_point<std::chrono::steady_clock> end;

  public:
    Timer()
    {
        start = std::chrono::high_resolution_clock::now();
    }
    ~Timer()
    {
        end = std::chrono::high_resolution_clock::now();
        auto duration = end - start;
        std::cout << "Function execution took  : " << duration.count() << " ns" << std::endl;
    }
};
int main()
{
    Timer t;
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...