Skip to content

Commit a26598b

Browse files
committed
Handling of small angles.
1 parent e0307ab commit a26598b

1 file changed

Lines changed: 12 additions & 4 deletions

File tree

numerics/angle_reduction_body.hpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22

33
#include "numerics/angle_reduction.hpp"
44

5+
#include <algorithm>
56
#include <cmath>
67
#include <limits>
78

89
#include "base/macros.hpp" // 🧙 For PRINCIPIA_USE_SSE3_INTRINSICS.
910
#include "numerics/double_precision.hpp"
11+
#include "numerics/elementary_functions.hpp"
1012
#include "numerics/payne_hanek.mathematica.h"
1113
#include "quantities/si.hpp"
1214

@@ -16,6 +18,7 @@ namespace _angle_reduction {
1618
namespace internal {
1719

1820
using namespace principia::numerics::_double_precision;
21+
using namespace principia::numerics::_elementary_functions;
1922
using namespace principia::numerics::_payne_hanek;
2023
using namespace principia::quantities::_si;
2124

@@ -175,7 +178,12 @@ void PayneHanek(Angle const& x,
175178
// Correct the mantissa and exponent to match [Mul97, p. 155].
176179
e--;
177180
X = std::scalbn(X, n);
178-
CHECK_GE(e, -1);
181+
if (e < -1) {
182+
DCHECK_LT(Abs(x), 0.5 * Radian);
183+
x_reduced = DoublePrecision<Angle>(x);
184+
quadrant = 0;
185+
return;
186+
}
179187

180188
// Split `X` so that the multiplications below are exact.
181189
double Xh;
@@ -185,7 +193,7 @@ void PayneHanek(Angle const& x,
185193
// Converts the bit numbering of [Mul97, p. 155] into our index in
186194
// `PayneHanekChunks`.
187195
auto bit_to_index = [](std::int64_t const b) {
188-
return -b / PayneHanekBitsPerChunk;
196+
return std::max(INT64_C(0), -b / PayneHanekBitsPerChunk);
189197
};
190198

191199
// `Medium(e, p)` is made of the chunks with indices [medium_first,
@@ -235,8 +243,8 @@ void PayneHanek(Angle const& x,
235243
// rounding, not x * (4 / π) with truncation.
236244
h = Scale(0.5, h);
237245

238-
// Because of the bound on `h` above, the fractional point is sure to be in
239-
// the `value`.
246+
// Because of the bound on `h` above, the fractional point cannot be in the
247+
// `error`.
240248
double const round_h = std::round(h.value);
241249
quadrant = static_cast<std::int64_t>(round_h) & 0b11;
242250
x_reduced = (h - round_h) * π_over_2;

0 commit comments

Comments
 (0)