Skip to content

Commit f0ab722

Browse files
committed
Try to get CI running but still missing coefs
1 parent b2a90f5 commit f0ab722

File tree

2 files changed

+106
-66
lines changed

2 files changed

+106
-66
lines changed

include/boost/decimal/detail/cmath/atan.hpp

Lines changed: 33 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -23,55 +23,6 @@ namespace decimal {
2323

2424
namespace detail {
2525

26-
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE T>
27-
constexpr auto atan_small_impl(T x) noexcept
28-
{
29-
return detail::atan_series_small(x);
30-
}
31-
32-
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE T>
33-
constexpr auto atan_med_impl(T x) noexcept
34-
{
35-
return detail::atan_series_med(x);
36-
}
37-
38-
template <typename T>
39-
constexpr auto atan_impl_cases(T x) noexcept
40-
BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T)
41-
{
42-
if (x <= std::numeric_limits<T>::epsilon())
43-
{
44-
return x;
45-
}
46-
else if (x <= T { 4375, -4 })
47-
{
48-
return detail::atan_small_impl(x);
49-
}
50-
else if (x <= T { 6875, -4 })
51-
{
52-
constexpr T atan_half { UINT64_C(4636476090008061162), -19 };
53-
54-
return atan_half + detail::atan_small_impl((x - T{5, -1}) / (1 + x / 2));
55-
}
56-
else if (x <= T{11875, -4})
57-
{
58-
constexpr T atan_one {UINT64_C(7853981633974483096), -19};
59-
60-
return atan_one + detail::atan_small_impl((x - 1) / (x + 1));
61-
}
62-
else if (x <= T { 24375, -4 })
63-
{
64-
constexpr T atan_three_halves {UINT64_C(9827937232473290679), -19};
65-
66-
return atan_three_halves + detail::atan_small_impl((x - T{15, -1}) / (1 + T{15, -1} * x));
67-
}
68-
else
69-
{
70-
// x <= T { 6 }
71-
return detail::atan_med_impl(x);
72-
}
73-
}
74-
7526
template <typename T>
7627
constexpr auto atan_impl(T x) noexcept
7728
BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T)
@@ -96,23 +47,45 @@ constexpr auto atan_impl(T x) noexcept
9647
}
9748
else
9849
{
99-
if (x <= T { 6 })
100-
{
101-
result = atan_impl_cases(x);
102-
}
103-
else if (x <= T { 24 })
50+
constexpr T one { 1 };
51+
52+
if (x <= T { 48 })
10453
{
105-
// The algorithm for arc-tangent of large-valued argument is based
106-
// on Chapter 11, page 194 of Cody and Waite, "Software Manual
107-
// for the Elementary Functions", Prentice Hall, 1980.
54+
const bool is_smallish { x <= T { 6 } };
10855

109-
const T f { ((x * numbers::sqrt3_v<T>) - T { 1 }) / (numbers::sqrt3_v<T> + x) };
56+
// The portion of the algorithm for arc-tangent of large-valued argument
57+
// is based on Chapter 11, page 194 of Cody and Waite, "Software Manual
58+
// for the Elementary Functions", Prentice Hall, 1980.
11059

111-
result = (numbers::pi_v<T> / static_cast<int>(INT8_C(6))) + atan_impl_cases(f);
60+
const T
61+
fx_arg
62+
{
63+
(!is_smallish)
64+
? ((x * numbers::sqrt3_v<T>) - one) / (numbers::sqrt3_v<T> + x)
65+
: x
66+
};
67+
68+
constexpr T my_pi_over_six { numbers::pi_v<T> / static_cast<int>(INT8_C(6)) };
69+
70+
constexpr T half { 5, -1 };
71+
constexpr T three_halves { 15, -1 };
72+
73+
result = (fx_arg <= std::numeric_limits<T>::epsilon()) ? fx_arg
74+
: (fx_arg <= T { 4375, -4 }) ? detail::atan_series_small (fx_arg)
75+
: (fx_arg <= T { 6875, -4 }) ? detail::atan_values<T>(0U) + detail::atan_series_small((fx_arg - half) / (one + fx_arg / 2))
76+
: (fx_arg <= T { 11875, -4 }) ? detail::atan_values<T>(1U) + detail::atan_series_small((fx_arg - one) / (fx_arg + one))
77+
: (fx_arg <= T { 24375, -4 }) ? detail::atan_values<T>(2U) + detail::atan_series_small((fx_arg - three_halves) / (one + three_halves * fx_arg))
78+
: detail::atan_series_med ( fx_arg)
79+
;
80+
81+
if(!is_smallish)
82+
{
83+
result += my_pi_over_six;
84+
}
11285
}
11386
else
11487
{
115-
result = my_pi_half - detail::atan_small_impl(1 / x);
88+
result = my_pi_half - detail::atan_series_small(one / x);
11689
}
11790
}
11891

include/boost/decimal/detail/cmath/impl/atan_impl.hpp

Lines changed: 73 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,28 @@ namespace atan_detail {
2525
template <bool b>
2626
struct 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

95147
template <bool b> constexpr std::array<decimal32, 11> atan_table_imp<b>::d32_coeffs_small;
96148
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;
97150

98151
template <bool b> constexpr std::array<decimal64, 11> atan_table_imp<b>::d64_coeffs_small;
99152
template <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>
108166
constexpr auto atan_series_small(T x) noexcept;
109167

110168
template <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

Comments
 (0)