Skip to content

Commit b9c37b7

Browse files
committed
Finish log1p impl/tests 128
1 parent e4c3c7d commit b9c37b7

File tree

3 files changed

+313
-85
lines changed

3 files changed

+313
-85
lines changed
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
// Copyright 2023 - 2024 Matt Borland
2+
// Copyright 2023 - 2024 Christopher Kormanyos
3+
// Distributed under the Boost Software License, Version 1.0.
4+
// https://www.boost.org/LICENSE_1_0.txt
5+
6+
#ifndef BOOST_DECIMAL_DETAIL_CMATH_IMPL_LOG1P_IMPL_HPP
7+
#define BOOST_DECIMAL_DETAIL_CMATH_IMPL_LOG1P_IMPL_HPP
8+
9+
#include <boost/decimal/detail/concepts.hpp>
10+
#include <boost/decimal/detail/cmath/impl/taylor_series_result.hpp>
11+
12+
#ifndef BOOST_DECIMAL_BUILD_MODULE
13+
#include <array>
14+
#include <cstddef>
15+
#include <cstdint>
16+
#endif
17+
18+
namespace boost {
19+
namespace decimal {
20+
namespace detail {
21+
22+
namespace log1p_detail {
23+
24+
template <bool b>
25+
struct log1p_table_imp
26+
{
27+
private:
28+
using d32_coeffs_t = std::array<decimal32, 12>;
29+
using d64_coeffs_t = std::array<decimal64, 20>;
30+
using d128_coeffs_t = std::array<decimal128, 36>;
31+
32+
public:
33+
static constexpr d32_coeffs_t d32_coeffs =
34+
{{
35+
// Series[Log[1 + x], {x, 0, 13}]
36+
// (1), // * z
37+
-boost::decimal::decimal32 { 5, -1 }, // * z^2
38+
boost::decimal::decimal32 { UINT64_C(3333333333333333333), -19 }, // * z^3
39+
-boost::decimal::decimal32 { 25, -2 }, // * z^4
40+
boost::decimal::decimal32 { 2, -1 }, // * z^5
41+
-boost::decimal::decimal32 { UINT64_C(1666666666666666667), -19 }, // * z^6
42+
boost::decimal::decimal32 { UINT64_C(1428571428571428571), -19 }, // * z^7
43+
-boost::decimal::decimal32 { 125, -3 }, // * z^8
44+
boost::decimal::decimal32 { UINT64_C(1111111111111111111), -19 }, // * z^9
45+
-boost::decimal::decimal32 { 1, -1 }, // * z^10
46+
boost::decimal::decimal32 { UINT64_C(9090909090909090909), -19 - 1 }, // * z^11
47+
-boost::decimal::decimal32 { UINT64_C(8333333333333333333), -19 - 1 }, // * z^12
48+
boost::decimal::decimal32 { UINT64_C(7692307692307692308), -19 - 1 }, // * z^13
49+
}};
50+
51+
static constexpr d64_coeffs_t d64_coeffs =
52+
{{
53+
// Series[Log[1 + x], {x, 0, 21}]
54+
// (1), // * z
55+
-boost::decimal::decimal64 { 5, -1 }, // * z^2
56+
boost::decimal::decimal64 { UINT64_C(3333333333333333333), -19 }, // * z^3
57+
-boost::decimal::decimal64 { 25, -2 }, // * z^4
58+
boost::decimal::decimal64 { 2, -1 }, // * z^5
59+
-boost::decimal::decimal64 { UINT64_C(1666666666666666667), -19 }, // * z^6
60+
boost::decimal::decimal64 { UINT64_C(1428571428571428571), -19 }, // * z^7
61+
-boost::decimal::decimal64 { 125, -3 }, // * z^8
62+
boost::decimal::decimal64 { UINT64_C(1111111111111111111), -19 }, // * z^9
63+
-boost::decimal::decimal64 { 1, -1 }, // * z^10
64+
boost::decimal::decimal64 { UINT64_C(9090909090909090909), -19 - 1 }, // * z^11
65+
-boost::decimal::decimal64 { UINT64_C(8333333333333333333), -19 - 1 }, // * z^12
66+
boost::decimal::decimal64 { UINT64_C(7692307692307692308), -19 - 1 }, // * z^13
67+
-boost::decimal::decimal64 { UINT64_C(7142857142857142857), -19 - 1 }, // * z^14
68+
boost::decimal::decimal64 { UINT64_C(6666666666666666667), -19 - 1 }, // * z^15
69+
-boost::decimal::decimal64 { UINT64_C(6250000000000000000), -19 - 1 }, // * z^16
70+
boost::decimal::decimal64 { UINT64_C(5882352941176470588), -19 - 1 }, // * z^17
71+
-boost::decimal::decimal64 { UINT64_C(5555555555555555556), -19 - 1 }, // * z^18
72+
boost::decimal::decimal64 { UINT64_C(5263157894736842105), -19 - 1 }, // * z^19
73+
-boost::decimal::decimal64 { 5, -2 }, // * z^20
74+
boost::decimal::decimal64 { UINT64_C(4761904761904761905), -19 - 1 }, // * z^21
75+
}};
76+
77+
static constexpr d128_coeffs_t d128_coeffs =
78+
{{
79+
// Series[Log[(1 + (z/2))/(1 - (z/2))], {z, 0, 43}]
80+
// (1), // * z
81+
-::boost::decimal::decimal128 { 5, -1 }, // * z^2
82+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(180700362080917), UINT64_C(7483252092553221458) }, -34 }, // * z^3
83+
-::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(135525271560688), UINT64_C(1000753050987528192) }, -34 }, // * z^4
84+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(108420217248550), UINT64_C(8179300070273843200) }, -34 }, // * z^5
85+
-::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(90350181040458), UINT64_C(12964998083131386532) }, -34 }, // * z^6
86+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(77443012320393), UINT64_C(3207108039665666332) }, -34 }, // * z^7
87+
-::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(67762635780344), UINT64_C(500376525493764096) }, -34 }, // * z^8
88+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(60233454026972), UINT64_C(8643332055420924359) }, -34 }, // * z^9
89+
-::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(54210108624275), UINT64_C(4089650035136921600) }, -34 }, // * z^10
90+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(492819169311592), UINT64_C(17054915875379776418) }, -35 }, // * z^11
91+
-::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(451750905202293), UINT64_C(9484758194528277842) }, -35 }, // * z^12
92+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(417000835571347), UINT64_C(15850062977145160938) }, -35 }, // * z^13
93+
-::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(387215061601965), UINT64_C(16035540198328331700) }, -35 }, // * z^14
94+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(361400724161834), UINT64_C(14966504185106442916) }, -35 }, // * z^15
95+
-::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(338813178901720), UINT64_C(2501882627468820480) }, -35 }, // * z^16
96+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(318882991907501), UINT64_C(5610020838860575434) }, -35 }, // * z^17
97+
-::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(301167270134862), UINT64_C(6323172129685518558) }, -35 }, // * z^18
98+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(285316361180395), UINT64_C(16670067533954968520) }, -35 }, // * z^19
99+
-::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(271050543121376), UINT64_C(2001506101975056384) }, -35 }, // * z^20
100+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(258143374401310), UINT64_C(10690360132218887800) }, -35 }, // * z^21
101+
-::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(246409584655796), UINT64_C(8527457937689888204) }, -35 }, // * z^22
102+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(235696124453370), UINT64_C(9760763598982462770) }, -35 }, // * z^23
103+
-::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(225875452601146), UINT64_C(13965751134118914724) }, -35 }, // * z^24
104+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(216840434497100), UINT64_C(16358600140547686400) }, -35 }, // * z^25
105+
-::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(208500417785673), UINT64_C(17148403525427356272) }, -35 }, // * z^26
106+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(200778180089908), UINT64_C(4215448086457012372) }, -35 }, // * z^27
107+
-::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(193607530800982), UINT64_C(17241142136018941658) }, -35 }, // * z^28
108+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(186931409049224), UINT64_C(16646619993397598836) }, -35 }, // * z^29
109+
-::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(180700362080917), UINT64_C(7483252092553221458) }, -35 }, // * z^30
110+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(174871318142823), UINT64_C(5456688082434451252) }, -35 }, // * z^31
111+
-::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(169406589450860), UINT64_C(1250941313734410240) }, -35 }, // * z^32
112+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(164273056437197), UINT64_C(11833886649696442678) }, -35 }, // * z^33
113+
-::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(159441495953750), UINT64_C(12028382456285063520) }, -35 }, // * z^34
114+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(154886024640786), UINT64_C(6414216079331332674) }, -35 }, // * z^35
115+
-::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(150583635067431), UINT64_C(3161586064842759274) }, -35 }, // * z^36
116+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(146513807092635), UINT64_C(13545911456276754540) }, -35 }, // * z^37
117+
}};
118+
};
119+
120+
#if !(defined(__cpp_inline_variables) && __cpp_inline_variables >= 201606L) && (!defined(_MSC_VER) || _MSC_VER != 1900)
121+
122+
template <bool b>
123+
constexpr typename log1p_table_imp<b>::d32_coeffs_t log1p_table_imp<b>::d32_coeffs;
124+
125+
template <bool b>
126+
constexpr typename log1p_table_imp<b>::d64_coeffs_t log1p_table_imp<b>::d64_coeffs;
127+
128+
template <bool b>
129+
constexpr typename log1p_table_imp<b>::d128_coeffs_t log1p_table_imp<b>::d128_coeffs;
130+
131+
#endif
132+
133+
} //namespace log1p_detail
134+
135+
using log1p_table = log1p_detail::log1p_table_imp<true>;
136+
137+
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE T>
138+
constexpr auto log1p_series_expansion(T z2) noexcept;
139+
140+
template <>
141+
constexpr auto log1p_series_expansion<decimal32>(decimal32 z2) noexcept
142+
{
143+
return taylor_series_result(z2, log1p_table::d32_coeffs);
144+
}
145+
146+
template <>
147+
constexpr auto log1p_series_expansion<decimal64>(decimal64 z2) noexcept
148+
{
149+
return taylor_series_result(z2, log1p_table::d64_coeffs);
150+
}
151+
152+
template <>
153+
constexpr auto log1p_series_expansion<decimal128>(decimal128 z2) noexcept
154+
{
155+
return taylor_series_result(z2, log1p_table::d128_coeffs);
156+
}
157+
158+
} //namespace detail
159+
} //namespace decimal
160+
} //namespace boost
161+
162+
#endif //BOOST_DECIMAL_DETAIL_CMATH_IMPL_LOG1P_IMPL_HPP

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

Lines changed: 6 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77
#define BOOST_DECIMAL_DETAIL_CMATH_LOG1P_HPP
88

99
#include <boost/decimal/fwd.hpp> // NOLINT(llvm-include-order)
10-
#include <boost/decimal/detail/type_traits.hpp>
10+
#include <boost/decimal/detail/cmath/impl/log1p_impl.hpp>
1111
#include <boost/decimal/detail/concepts.hpp>
1212
#include <boost/decimal/detail/config.hpp>
13+
#include <boost/decimal/detail/type_traits.hpp>
1314
#include <boost/decimal/numbers.hpp>
1415

1516
#ifndef BOOST_DECIMAL_BUILD_MODULE
@@ -20,10 +21,8 @@
2021
namespace boost {
2122
namespace decimal {
2223

23-
namespace detail {
24-
25-
template <typename T>
26-
constexpr auto log1p_impl(T x) noexcept
24+
BOOST_DECIMAL_EXPORT template <typename T>
25+
constexpr auto log1p(T x) noexcept
2726
BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T)
2827
{
2928
const auto fpc = fpclassify(x);
@@ -74,84 +73,15 @@ constexpr auto log1p_impl(T x) noexcept
7473
}
7574
else
7675
{
77-
using coefficient_array_type = std::array<T, static_cast<std::size_t>(UINT8_C(21))>;
78-
79-
#if (defined(__clang__) && (__clang__ < 6))
80-
# pragma clang diagnostic push
81-
# pragma clang diagnostic ignored "-Wmissing-braces"
82-
#endif
83-
84-
constexpr auto coefficient_table =
85-
coefficient_array_type
86-
{
87-
// Series[Log[1+x], {x, 0, 21}]
88-
89-
T { 1, 0 }, // x
90-
-T { 5, -1}, // (-1 / 2) * x^2
91-
T { UINT64_C(333333333333333333), -18 }, // ( 1 / 3) * x^3
92-
-T { 25, -2 }, // (-1 / 4) * x^4
93-
T { 2, -1 }, // ( 1 / 5) * x^5
94-
-T { UINT64_C(166666666666666667), -18 }, // ( 1 / 6) * x^6
95-
T { UINT64_C(142857142857142857), -18 }, // ( 1 / 7) * x^7
96-
-T { 125, -3 }, // (-1 / 8) * x^8
97-
T { UINT64_C(111111111111111111), -18 }, // ( 1 / 9) * x^9
98-
-T { 1, -1 }, // (-1 / 10) * x^10
99-
T { UINT64_C(909090909090909091), -18 - 1 }, // ( 1 / 11) * x^11
100-
-T { UINT64_C(833333333333333333), -18 - 1 }, // (-1 / 12) * x^12
101-
T { UINT64_C(769230769230769230), -18 - 1 }, // ( 1 / 13) * x^13
102-
-T { UINT64_C(714285714285714286), -18 - 1 }, // (-1 / 14) * x^14
103-
T { UINT64_C(666666666666666667), -18 - 1 }, // ( 1 / 15) * x^15
104-
-T { UINT64_C(625000000000000000), -18 - 1 }, // ( 1 / 16) * x^16
105-
T { UINT64_C(588235294117647059), -18 - 1 }, // ( 1 / 17) * x^17
106-
-T { UINT64_C(555555555555555556), -18 - 1 }, // ( 1 / 18) * x^18
107-
T { UINT64_C(526315789473684211), -18 - 1 }, // ( 1 / 19) * x^19
108-
-T { 5, -2 }, // ( 1 / 20) * x^20
109-
T { UINT64_C(476190476190476190), -18 - 1 } // ( 1 / 21) * x^21
110-
};
111-
112-
#if (defined(__clang__) && (__clang__ < 6))
113-
# pragma clang diagnostic pop
114-
#endif
115-
116-
auto rit = coefficient_table.crbegin() + static_cast<std::size_t>((sizeof(T) == 4U) ? 7U : 0U);
117-
118-
result = *rit;
119-
120-
while(rit != coefficient_table.crend())
121-
{
122-
result = fma(result, x, *rit++);
123-
}
124-
76+
result = detail::log1p_series_expansion(x);
77+
result = fma(result, x, one);
12578
result *= x;
12679
}
12780
}
12881

12982
return result;
13083
}
13184

132-
} // namespace detail
133-
134-
BOOST_DECIMAL_EXPORT template <typename T>
135-
constexpr auto log1p(T x) noexcept
136-
BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T)
137-
{
138-
#if BOOST_DECIMAL_DEC_EVAL_METHOD == 0
139-
140-
using evaluation_type = T;
141-
142-
#elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1
143-
144-
using evaluation_type = detail::promote_args_t<T, decimal64>;
145-
146-
#else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2
147-
148-
using evaluation_type = detail::promote_args_t<T, decimal128>;
149-
150-
#endif
151-
152-
return static_cast<T>(detail::log1p_impl(static_cast<evaluation_type>(x)));
153-
}
154-
15585
} // namespace decimal
15686
} // namespace boost
15787

0 commit comments

Comments
 (0)