如何在C ++中处理-nan输出

时间:2018-08-29 19:32:20

标签: c++ c++11

假设我有一个计算一对点之间的欧几里得距离的函数。 pointpoint_pair是定义为的两个结构:

struct point {
    int x, y;
}

struct point_pair {
    point a, b;
}

以下功能以一对点作为输入来计算距离:

double calc_distance(point_pair pair)
{
  return (sqrt((pair.a.x - pair.b.x) * (pair.a.x - pair.b.x) + (pair.a.y - pair.b.y) * (pair.a.y - pair.b.y)));
}

该功能适用​​于较小的点对值;但是对于点对,例如:

651760491 595516649
716636914 955747792

输出为-nan

我不确定如何解决此问题,我还应该使用其他方法代替double吗?

这是完整的代码:https://pastebin.com/5XEr9bTD

2 个答案:

答案 0 :(得分:5)

正确的方法是使用标准hypot()函数。

https://en.cppreference.com/w/cpp/numeric/math/hypot

“计算x和y的平方和的平方根,在计算的中间阶段不会出现不适当的上溢或下溢。”

答案 1 :(得分:2)

最好不要使用int作为点坐标:

#include <iostream>
#include <cmath>

struct point { double x, y; };

struct point_pair { point a, b; };

double calc_distance(point_pair pair) {
    return (std::sqrt((pair.a.x - pair.b.x) * (pair.a.x - pair.b.x) + (pair.a.y - pair.b.y) * (pair.a.y - pair.b.y)));
}

int main() {
    point_pair pp{{651760491, 595516649}
            , {716636914, 955747792}};
    std::cout << calc_distance(pp) << '\n';
}

但是,如果您有这样做的理由,那么至少将坐标差转换为double

struct point { int x, y; };

struct point_pair { point a, b; };

double calc_distance(point_pair pair) {
    return (std::sqrt(double(pair.a.x - pair.b.x) * (pair.a.x - pair.b.x) + double(pair.a.y - pair.b.y) * (pair.a.y - pair.b.y)));
}

因为否则,您将面临大订单的整数溢出,而有符号溢出是C ++中的UB。