假设我有一个函数来计算一对点之间的欧几里德距离。 point
和point_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
我不知道如何解决这个问题,还有什么我应该用来代替双重的吗?
这是完整的代码:https://pastebin.com/5XEr9bTD
最好不要使用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。
正确的方法是使用标准的hypot()
功能。
https://en.cppreference.com/w/cpp/numeric/math/hypot
“计算x和y的平方和的平方根,在计算的中间阶段没有过度溢出或下溢。”