Skip to content

Commit db31aa7

Browse files
committed
Clamp inputs to arcHav and computeOffset to prevent NaN
1 parent 4406a5b commit db31aa7

3 files changed

Lines changed: 9 additions & 2 deletions

File tree

include/MathUtil.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ class MathUtil {
9494
* The argument must be in [0, 1], and the result is positive.
9595
*/
9696
static inline double arcHav(double x) {
97-
return 2.0 * asin(sqrt(x));
97+
return 2.0 * asin(sqrt(clamp(x, 0.0, 1.0)));
9898
}
9999

100100
// Given h==hav(x), returns sin(abs(x)).

include/SphericalUtil.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class SphericalUtil {
6666
sinDistance * cosFromLat * sin(heading),
6767
cosDistance - sinFromLat * sinLat);
6868

69-
return LatLng(rad2deg(asin(sinLat)), rad2deg(fromLng + dLng));
69+
return LatLng(rad2deg(asin(MathUtil::clamp(sinLat, -1.0, 1.0))), rad2deg(fromLng + dLng));
7070
}
7171

7272

tests/MathUtil/mod.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ TEST(MathUtil, hav_arcHav) {
6060
EXPECT_NEAR(MathUtil::arcHav(MathUtil::hav(1.2)), 1.2, 1e-10);
6161
}
6262

63+
TEST(MathUtil, arcHav_clamp) {
64+
// Floating-point rounding can push the haversine value slightly outside [0,1].
65+
// arcHav must clamp rather than pass a bad value to sqrt/asin and return NaN.
66+
EXPECT_NEAR(MathUtil::arcHav( 1.0 + 1e-15), M_PI, 1e-9); // x > 1 → clamp to π
67+
EXPECT_NEAR(MathUtil::arcHav(-1e-15), 0.0, 1e-9); // x < 0 → clamp to 0
68+
}
69+
6370
TEST(MathUtil, sinFromHav) {
6471
EXPECT_NEAR(MathUtil::sinFromHav(0.0), 0.0, 1e-10); // sin(0) == 0
6572
EXPECT_NEAR(MathUtil::sinFromHav(0.5), 1.0, 1e-10); // sin(π/2) == 1

0 commit comments

Comments
 (0)