@@ -25,7 +25,28 @@ namespace atan_detail {
2525template <bool b>
2626struct atan_table_imp
2727{
28- // 10th degree remez polynomial calculated from 0, 2.4375
28+ static constexpr std::array<::boost::decimal::decimal32, 3 > d32_atan_values =
29+ {{
30+ ::boost::decimal::decimal32 { UINT64_C (4636476090008061162 ), -19 }, // atan_half
31+ ::boost::decimal::decimal32 { UINT64_C (7853981633974483096 ), -19 }, // atan_one
32+ ::boost::decimal::decimal32 { UINT64_C (9827937232473290679 ), -19 }, // atan_three_halves
33+ }};
34+
35+ static constexpr std::array<::boost::decimal::decimal64, 3 > d64_atan_values =
36+ {{
37+ ::boost::decimal::decimal64 { UINT64_C (4636476090008061162 ), -19 }, // atan_half
38+ ::boost::decimal::decimal64 { UINT64_C (7853981633974483096 ), -19 }, // atan_one
39+ ::boost::decimal::decimal64 { UINT64_C (9827937232473290679 ), -19 }, // atan_three_halves
40+ }};
41+
42+ static constexpr std::array<::boost::decimal::decimal128, 3 > d128_atan_values =
43+ {{
44+ ::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C (251343872473191 ), UINT64_C (15780610568723885484 ) }, -34 }, // atan_half
45+ ::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C (425765197510819 ), UINT64_C (5970600460659265246 ) }, -34 }, // atan_one
46+ ::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C (532773544924935 ), UINT64_C (16408933314882201700 ) }, -34 }, // atan_three_halves
47+ }};
48+
49+ // 10th degree remez polynomial calculated from 0, 0.4375
2950 // Estimated max error: 2.3032664387910605e-12
3051 static constexpr std::array<::boost::decimal::decimal32, 11 > d32_coeffs_small =
3152 {{
@@ -57,6 +78,21 @@ struct atan_table_imp
5778 ::boost::decimal::decimal64 { UINT64_C (23032664387910606 ), -29 },
5879 }};
5980
81+ static constexpr std::array<::boost::decimal::decimal128, 11 > d128_coeffs_small =
82+ {{
83+ ::boost::decimal::decimal128 { UINT64_C (61037779951304161 ), -18 , true },
84+ ::boost::decimal::decimal128 { UINT64_C (10723099589331457 ), -17 },
85+ ::boost::decimal::decimal128 { UINT64_C (22515613909953665 ), -18 },
86+ ::boost::decimal::decimal128 { UINT64_C (15540713402718176 ), -17 , true },
87+ ::boost::decimal::decimal128 { UINT64_C (35999727706986597 ), -19 },
88+ ::boost::decimal::decimal128 { UINT64_C (19938867353282852 ), -17 },
89+ ::boost::decimal::decimal128 { UINT64_C (62252075283915644 ), -22 },
90+ ::boost::decimal::decimal128 { UINT64_C (33333695504913247 ), -17 , true },
91+ ::boost::decimal::decimal128 { UINT64_C (10680927642397763 ), -24 },
92+ ::boost::decimal::decimal128 { UINT64_C (99999999877886492 ), -17 },
93+ ::boost::decimal::decimal128 { UINT64_C (23032664387910606 ), -29 },
94+ }};
95+
6096 // 10th degree remez polynomial from 2.4375, 6
6197 // Estimated max error: 2.6239664084435361e-9
6298 static constexpr std::array<::boost::decimal::decimal32, 11 > d32_coeffs_med =
@@ -88,15 +124,37 @@ struct atan_table_imp
88124 ::boost::decimal::decimal64 { UINT64_C (15738722141839421 ), -16 },
89125 ::boost::decimal::decimal64 { UINT64_C (1425850153011925 ), -16 , true },
90126 }};
127+
128+ static constexpr std::array<::boost::decimal::decimal128, 11 > d128_coeffs_med =
129+ {{
130+ ::boost::decimal::decimal128 { UINT64_C (35895331641408534 ), -24 , true },
131+ ::boost::decimal::decimal128 { UINT64_C (1734850544519432 ), -21 },
132+ ::boost::decimal::decimal128 { UINT64_C (38064221484608425 ), -21 , true },
133+ ::boost::decimal::decimal128 { UINT64_C (50135011697517902 ), -20 },
134+ ::boost::decimal::decimal128 { UINT64_C (44154446962804779 ), -19 , true },
135+ ::boost::decimal::decimal128 { UINT64_C (27400572833763747 ), -18 },
136+ ::boost::decimal::decimal128 { UINT64_C (12289830364128736 ), -17 , true },
137+ ::boost::decimal::decimal128 { UINT64_C (40157034119189716 ), -17 },
138+ ::boost::decimal::decimal128 { UINT64_C (94842703533437844 ), -17 , true },
139+ ::boost::decimal::decimal128 { UINT64_C (15738722141839421 ), -16 },
140+ ::boost::decimal::decimal128 { UINT64_C (1425850153011925 ), -16 , true },
141+ }};
142+
91143};
92144
93145#if !(defined(__cpp_inline_variables) && __cpp_inline_variables >= 201606L) && (!defined(_MSC_VER) || _MSC_VER != 1900)
94146
95147template <bool b> constexpr std::array<decimal32, 11 > atan_table_imp<b>::d32_coeffs_small;
96148template <bool b> constexpr std::array<decimal32, 11 > atan_table_imp<b>::d32_coeffs_med;
149+ template <bool b> constexpr std::array<decimal32, 3 > atan_table_imp<b>::d32_atan_values;
97150
98151template <bool b> constexpr std::array<decimal64, 11 > atan_table_imp<b>::d64_coeffs_small;
99152template <bool b> constexpr std::array<decimal64, 11 > atan_table_imp<b>::d64_coeffs_med;
153+ template <bool b> constexpr std::array<decimal64, 3 > atan_table_imp<b>::d64_atan_values;
154+
155+ template <bool b> constexpr std::array<decimal128, 11 > atan_table_imp<b>::d128_coeffs_small;
156+ template <bool b> constexpr std::array<decimal128, 11 > atan_table_imp<b>::d128_coeffs_med;
157+ template <bool b> constexpr std::array<decimal128, 3 > atan_table_imp<b>::d128_atan_values;
100158
101159#endif
102160
@@ -108,13 +166,22 @@ template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE T>
108166constexpr auto atan_series_small (T x) noexcept ;
109167
110168template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE T>
111- constexpr auto atan_series_med (T x) noexcept ;
169+ constexpr auto atan_series_med (T x) noexcept ;
170+
171+ template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE T>
172+ constexpr auto atan_values (std::size_t idx) noexcept -> T;
173+
174+ template <> constexpr auto atan_series_small<decimal32> (decimal32 x) noexcept { return remez_series_result (x, atan_detail::atan_table::d32_coeffs_small); }
175+ template <> constexpr auto atan_series_small<decimal64> (decimal64 x) noexcept { return remez_series_result (x, atan_detail::atan_table::d64_coeffs_small); }
176+ template <> constexpr auto atan_series_small<decimal128>(decimal128 x) noexcept { return remez_series_result (x, atan_detail::atan_table::d128_coeffs_small); }
112177
113- template <> constexpr auto atan_series_small<decimal32>(decimal32 x) noexcept { return remez_series_result (x, atan_detail::atan_table::d32_coeffs_small); }
114- template <> constexpr auto atan_series_med <decimal32>(decimal32 x) noexcept { return remez_series_result (x, atan_detail::atan_table::d32_coeffs_med ); }
178+ template <> constexpr auto atan_series_med <decimal32> (decimal32 x) noexcept { return remez_series_result (x, atan_detail::atan_table::d32_coeffs_med ); }
179+ template <> constexpr auto atan_series_med <decimal64> (decimal64 x) noexcept { return remez_series_result (x, atan_detail::atan_table::d64_coeffs_med ); }
180+ template <> constexpr auto atan_series_med <decimal128>(decimal128 x) noexcept { return remez_series_result (x, atan_detail::atan_table::d128_coeffs_med ); }
115181
116- template <> constexpr auto atan_series_small<decimal64>(decimal64 x) noexcept { return remez_series_result (x, atan_detail::atan_table::d64_coeffs_small); }
117- template <> constexpr auto atan_series_med <decimal64>(decimal64 x) noexcept { return remez_series_result (x, atan_detail::atan_table::d64_coeffs_med ); }
182+ template <> constexpr auto atan_values<decimal32> (std::size_t idx) noexcept -> decimal32 { return atan_detail::atan_table::d32_atan_values [idx]; }
183+ template <> constexpr auto atan_values<decimal64> (std::size_t idx) noexcept -> decimal64 { return atan_detail::atan_table::d64_atan_values [idx]; }
184+ template <> constexpr auto atan_values<decimal128>(std::size_t idx) noexcept -> decimal128 { return atan_detail::atan_table::d128_atan_values[idx]; }
118185
119186} // namespace detail
120187} // namespace decimal
0 commit comments