@@ -48,7 +48,7 @@ struct atan_table_imp
4848
4949 // 10th degree remez polynomial calculated from 0, 0.4375
5050 // Estimated max error: 2.3032664387910605e-12
51- static constexpr std::array<::boost::decimal::decimal32, 11 > d32_coeffs_small =
51+ static constexpr std::array<::boost::decimal::decimal32, 11 > d32_coeffs =
5252 {{
5353 ::boost::decimal::decimal32 { UINT64_C (61037779951304161 ), -18 , true },
5454 ::boost::decimal::decimal32 { UINT64_C (10723099589331457 ), -17 },
@@ -63,7 +63,7 @@ struct atan_table_imp
6363 ::boost::decimal::decimal32 { UINT64_C (23032664387910606 ), -29 },
6464 }};
6565
66- static constexpr std::array<::boost::decimal::decimal64, 11 > d64_coeffs_small =
66+ static constexpr std::array<::boost::decimal::decimal64, 11 > d64_coeffs =
6767 {{
6868 ::boost::decimal::decimal64 { UINT64_C (61037779951304161 ), -18 , true },
6969 ::boost::decimal::decimal64 { UINT64_C (10723099589331457 ), -17 },
@@ -77,83 +77,15 @@ struct atan_table_imp
7777 ::boost::decimal::decimal64 { UINT64_C (99999999877886492 ), -17 },
7878 ::boost::decimal::decimal64 { UINT64_C (23032664387910606 ), -29 },
7979 }};
80-
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-
96- // 10th degree remez polynomial from 2.4375, 6
97- // Estimated max error: 2.6239664084435361e-9
98- static constexpr std::array<::boost::decimal::decimal32, 11 > d32_coeffs_med =
99- {{
100- ::boost::decimal::decimal32 { UINT64_C (35895331641408534 ), -24 , true },
101- ::boost::decimal::decimal32 { UINT64_C (1734850544519432 ), -21 },
102- ::boost::decimal::decimal32 { UINT64_C (38064221484608425 ), -21 , true },
103- ::boost::decimal::decimal32 { UINT64_C (50135011697517902 ), -20 },
104- ::boost::decimal::decimal32 { UINT64_C (44154446962804779 ), -19 , true },
105- ::boost::decimal::decimal32 { UINT64_C (27400572833763747 ), -18 },
106- ::boost::decimal::decimal32 { UINT64_C (12289830364128736 ), -17 , true },
107- ::boost::decimal::decimal32 { UINT64_C (40157034119189716 ), -17 },
108- ::boost::decimal::decimal32 { UINT64_C (94842703533437844 ), -17 , true },
109- ::boost::decimal::decimal32 { UINT64_C (15738722141839421 ), -16 },
110- ::boost::decimal::decimal32 { UINT64_C (1425850153011925 ), -16 , true },
111- }};
112-
113- static constexpr std::array<::boost::decimal::decimal64, 11 > d64_coeffs_med =
114- {{
115- ::boost::decimal::decimal64 { UINT64_C (35895331641408534 ), -24 , true },
116- ::boost::decimal::decimal64 { UINT64_C (1734850544519432 ), -21 },
117- ::boost::decimal::decimal64 { UINT64_C (38064221484608425 ), -21 , true },
118- ::boost::decimal::decimal64 { UINT64_C (50135011697517902 ), -20 },
119- ::boost::decimal::decimal64 { UINT64_C (44154446962804779 ), -19 , true },
120- ::boost::decimal::decimal64 { UINT64_C (27400572833763747 ), -18 },
121- ::boost::decimal::decimal64 { UINT64_C (12289830364128736 ), -17 , true },
122- ::boost::decimal::decimal64 { UINT64_C (40157034119189716 ), -17 },
123- ::boost::decimal::decimal64 { UINT64_C (94842703533437844 ), -17 , true },
124- ::boost::decimal::decimal64 { UINT64_C (15738722141839421 ), -16 },
125- ::boost::decimal::decimal64 { UINT64_C (1425850153011925 ), -16 , true },
126- }};
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-
14380};
14481
14582#if !(defined(__cpp_inline_variables) && __cpp_inline_variables >= 201606L) && (!defined(_MSC_VER) || _MSC_VER != 1900)
14683
147- template <bool b> constexpr std::array<decimal32, 11 > atan_table_imp<b>::d32_coeffs_small;
148- template <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;
84+ template <bool b> constexpr std::array<decimal32, 11 > atan_table_imp<b>::d32_coeffs;
85+ template <bool b> constexpr std::array<decimal64, 11 > atan_table_imp<b>::d64_coeffs;
15086
151- template <bool b> constexpr std::array<decimal64, 11 > atan_table_imp<b>::d64_coeffs_small;
152- template <bool b> constexpr std::array<decimal64, 11 > atan_table_imp<b>::d64_coeffs_med;
87+ template <bool b> constexpr std::array<decimal32, 3 > atan_table_imp<b>::d32_atan_values;
15388template <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;
15789template <bool b> constexpr std::array<decimal128, 3 > atan_table_imp<b>::d128_atan_values;
15890
15991#endif
@@ -163,21 +95,56 @@ using atan_table = atan_table_imp<true>;
16395} // namespace atan_detail
16496
16597template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE T>
166- constexpr auto atan_series_small (T x) noexcept ;
167-
168- template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE T>
169- constexpr auto atan_series_med (T x) noexcept ;
98+ constexpr auto atan_series (T x) noexcept ;
17099
171100template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE T>
172101constexpr auto atan_values (std::size_t idx) noexcept -> T;
173102
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); }
103+ template <> constexpr auto atan_series<decimal32> (decimal32 x) noexcept { return remez_series_result (x, atan_detail::atan_table::d32_coeffs); }
104+ template <> constexpr auto atan_series<decimal64> (decimal64 x) noexcept { return remez_series_result (x, atan_detail::atan_table::d64_coeffs); }
177105
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 ); }
106+ template <>
107+ constexpr auto atan_series<decimal128>(decimal128 x) noexcept
108+ {
109+ // PadeApproximant[ArcTan[x]/x, {x, 0, {18, 18}}]
110+ // FullSimplify[%]
111+ // HornerForm[Numerator[Out[2]]]
112+ // HornerForm[Denominator[Out[2]]]
113+
114+ const decimal128 x2 { x * x };
115+
116+ const decimal128
117+ top
118+ {
119+ decimal128 { UINT64_C (21427381364263875 ) }
120+ + x2 * (decimal128 { UINT64_C (91886788553059500 ) }
121+ + x2 * (decimal128 { UINT64_C (163675410390191700 ) }
122+ + x2 * (decimal128 { UINT64_C (156671838074852100 ) }
123+ + x2 * (decimal128 { UINT64_C (87054123957610810 ) }
124+ + x2 * (decimal128 { UINT64_C (28283323008669300 ) }
125+ + x2 * (decimal128 { UINT64_C (5134145876036100 ) }
126+ + x2 * (decimal128 { UINT64_C (463911017673180 ) }
127+ + x2 * (decimal128 { UINT64_C (16016872057515 ) }
128+ + decimal128 { UINT64_C (90194313216 ) } * x2))))))))
129+ };
130+
131+ const decimal128
132+ bot
133+ {
134+ decimal128 { UINT64_C (21427381364263875 ) }
135+ + x2 * (decimal128 { UINT64_C (99029249007814125 ) }
136+ + x2 * (decimal128 { UINT64_C (192399683786610300 ) }
137+ + x2 * (decimal128 { UINT64_C (204060270682768500 ) }
138+ + x2 * (decimal128 { UINT64_C (128360492848838250 ) }
139+ + x2 * (decimal128 { UINT64_C (48688462804731750 ) }
140+ + x2 * (decimal128 { UINT64_C (10819658401051500 ) }
141+ + x2 * (decimal128 { UINT64_C (1298359008126180 ) }
142+ + x2 * (decimal128 { UINT64_C (70562989572075 ) }
143+ + decimal128 { UINT64_C (1120047453525 ) } * x2))))))))
144+ };
145+
146+ return (x * top) / bot;
147+ }
181148
182149template <> constexpr auto atan_values<decimal32> (std::size_t idx) noexcept -> decimal32 { return atan_detail::atan_table::d32_atan_values [idx]; }
183150template <> constexpr auto atan_values<decimal64> (std::size_t idx) noexcept -> decimal64 { return atan_detail::atan_table::d64_atan_values [idx]; }
0 commit comments