Skip to content

Commit 7f74bc0

Browse files
authored
Merge pull request #529 from cppalliance/sinh128
2 parents de795d4 + 2de3757 commit 7f74bc0

File tree

5 files changed

+291
-63
lines changed

5 files changed

+291
-63
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ struct cosh_table_imp
3232
public:
3333
static constexpr d32_coeffs_t d32_coeffs =
3434
{{
35-
// Series[Cosh[x], {x, 0, 10}]
35+
// Series[Cosh[x], {x, 0, 12}]
3636
// (1), // * 1
3737
::boost::decimal::decimal32 { 5, -1 }, // * x^2
3838
::boost::decimal::decimal32 { UINT64_C(4166666666666666667), - 19 - 1 }, // * x^6
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
// Copyright 2024 Matt Borland
2+
// Copyright 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_SINH_IMPL_HPP
7+
#define BOOST_DECIMAL_DETAIL_CMATH_IMPL_SINH_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 sinh_detail {
23+
24+
template <bool b>
25+
struct sinh_table_imp
26+
{
27+
private:
28+
using d32_coeffs_t = std::array<decimal32, 6>;
29+
using d64_coeffs_t = std::array<decimal64, 9>;
30+
using d128_coeffs_t = std::array<decimal128, 17>;
31+
32+
public:
33+
static constexpr d32_coeffs_t d32_coeffs =
34+
{{
35+
// Series[Sinh[x], {x, 0, 13}]
36+
// (1), // * x
37+
::boost::decimal::decimal32 { UINT64_C(1666666666666666667), - 19 - 0 }, // * x^3
38+
::boost::decimal::decimal32 { UINT64_C(8333333333333333333), - 19 - 2 }, // * x^5
39+
::boost::decimal::decimal32 { UINT64_C(1984126984126984127), - 19 - 3 }, // * x^7
40+
::boost::decimal::decimal32 { UINT64_C(2755731922398589065), - 19 - 5 }, // * x^9
41+
::boost::decimal::decimal32 { UINT64_C(2505210838544171878), - 19 - 7 }, // * x^11
42+
::boost::decimal::decimal32 { UINT64_C(1605904383682161460), - 19 - 9 }, // * x^13
43+
}};
44+
45+
static constexpr d64_coeffs_t d64_coeffs =
46+
{{
47+
// Series[Sinh[x], {x, 0, 19}]
48+
// (1), // * x
49+
::boost::decimal::decimal64 { UINT64_C(1666666666666666667), - 19 - 0 }, // * x^3
50+
::boost::decimal::decimal64 { UINT64_C(8333333333333333333), - 19 - 2 }, // * x^5
51+
::boost::decimal::decimal64 { UINT64_C(1984126984126984127), - 19 - 3 }, // * x^7
52+
::boost::decimal::decimal64 { UINT64_C(2755731922398589065), - 19 - 5 }, // * x^9
53+
::boost::decimal::decimal64 { UINT64_C(2505210838544171878), - 19 - 7 }, // * x^11
54+
::boost::decimal::decimal64 { UINT64_C(1605904383682161460), - 19 - 9 }, // * x^13
55+
::boost::decimal::decimal64 { UINT64_C(7647163731819816476), - 19 - 12 }, // * x^15
56+
::boost::decimal::decimal64 { UINT64_C(2811457254345520763), - 19 - 14 }, // * x^17
57+
::boost::decimal::decimal64 { UINT64_C(8220635246624329717), - 19 - 17 } // * x^19
58+
}};
59+
60+
static constexpr d128_coeffs_t d128_coeffs =
61+
{{
62+
// Series[Cosh[x], {x, 0, 34}]
63+
// (1), // * x
64+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(90350181040458), UINT64_C(12964998083131386532) }, -34 }, // * x^3
65+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(451750905202293), UINT64_C(9484758194528277842) }, -36 }, // * x^5
66+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(107559739333879), UINT64_C(7528774067376128516) }, -37 }, // * x^7
67+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(149388526852610), UINT64_C(5332535073103080820) }, -39 }, // * x^9
68+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(135807751684191), UINT64_C(3170782423392841514) }, -41 }, // * x^11
69+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(87056251079609), UINT64_C(13384395342406417346) }, -43 }, // * x^13
70+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(414553576569570), UINT64_C(2246069003855862950) }, -46 }, // * x^15
71+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(152409403150577), UINT64_C(4623619737181327888) }, -48 }, // * x^17
72+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(445641529680050), UINT64_C(8125571139796411480) }, -51 }, // * x^19
73+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(106105126114297), UINT64_C(13354072793200296588) }, -53 }, // * x^21
74+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(209693925127070), UINT64_C(11079921506407677690) }, -56 }, // * x^23
75+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(349489875211784), UINT64_C(6168706461539761736) }, -59 }, // * x^25
76+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(497848825088011), UINT64_C(16092452014289198134) }, -62 }, // * x^27
77+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(61311431661085), UINT64_C(3799242275031630472) }, -64 }, // * x^29
78+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(65926270603317), UINT64_C(7853896396813382020) }, -67 }, // * x^31
79+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(62430180495565), UINT64_C(13726064643322746782) }, -70 }, // * x^33
80+
::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(524623365508955), UINT64_C(15360627863698201590) }, -74 }, // * x^35
81+
}};
82+
};
83+
84+
#if !(defined(__cpp_inline_variables) && __cpp_inline_variables >= 201606L) && (!defined(_MSC_VER) || _MSC_VER != 1900)
85+
86+
template <bool b>
87+
constexpr typename sinh_table_imp<b>::d32_coeffs_t sinh_table_imp<b>::d32_coeffs;
88+
89+
template <bool b>
90+
constexpr typename sinh_table_imp<b>::d64_coeffs_t sinh_table_imp<b>::d64_coeffs;
91+
92+
template <bool b>
93+
constexpr typename sinh_table_imp<b>::d128_coeffs_t sinh_table_imp<b>::d128_coeffs;
94+
95+
#endif
96+
97+
} //namespace sinh_detail
98+
99+
using sinh_table = sinh_detail::sinh_table_imp<true>;
100+
101+
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE T>
102+
constexpr auto sinh_series_expansion(T z) noexcept;
103+
104+
template <>
105+
constexpr auto sinh_series_expansion<decimal32>(decimal32 z2) noexcept
106+
{
107+
return taylor_series_result(z2, sinh_table::d32_coeffs);
108+
}
109+
110+
template <>
111+
constexpr auto sinh_series_expansion<decimal64>(decimal64 z2) noexcept
112+
{
113+
return taylor_series_result(z2, sinh_table::d64_coeffs);
114+
}
115+
116+
template <>
117+
constexpr auto sinh_series_expansion<decimal128>(decimal128 z2) noexcept
118+
{
119+
return taylor_series_result(z2, sinh_table::d128_coeffs);
120+
}
121+
122+
} //namespace detail
123+
} //namespace decimal
124+
} //namespace boost
125+
126+
#endif //BOOST_DECIMAL_DETAIL_CMATH_IMPL_SINH_IMPL_HPP

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

Lines changed: 5 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
// Copyright 2023 Matt Borland
2-
// Copyright 2023 Christopher Kormanyos
1+
// Copyright 2023 - 2024 Matt Borland
2+
// Copyright 2023 - 2024 Christopher Kormanyos
33
// Distributed under the Boost Software License, Version 1.0.
44
// https://www.boost.org/LICENSE_1_0.txt
55

66
#ifndef BOOST_DECIMAL_DETAIL_CMATH_SINH_HPP
77
#define BOOST_DECIMAL_DETAIL_CMATH_SINH_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/sinh_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
@@ -57,48 +58,9 @@ constexpr auto sinh(T x) noexcept
5758

5859
if (x < one)
5960
{
60-
using coefficient_array_type = std::array<T, static_cast<std::size_t>(UINT8_C(9))>;
61-
62-
#if (defined(__clang__) && (__clang__ < 6))
63-
# pragma clang diagnostic push
64-
# pragma clang diagnostic ignored "-Wmissing-braces"
65-
#endif
66-
67-
constexpr auto coefficient_table =
68-
coefficient_array_type
69-
{
70-
// Series[Sinh[x], {x, 0, 19}]
71-
// (1), // * x
72-
T { UINT64_C(166666666666666667), -18 - 0 }, // * x^3
73-
T { UINT64_C(833333333333333333), -18 - 2 }, // * x^5
74-
T { UINT64_C(198412698412698413), -18 - 3 }, // * x^7
75-
T { UINT64_C(275573192239858907), -18 - 5 }, // * x^9
76-
T { UINT64_C(250521083854417188), -18 - 7 }, // * x^11
77-
T { UINT64_C(160590438368216146), -18 - 9 }, // * x^13
78-
T { UINT64_C(764716373181981648), -18 - 12 }, // * x^15
79-
T { UINT64_C(281145725434552076), -18 - 14 }, // * x^17
80-
T { UINT64_C(822063524662432972), -18 - 17 }, // * x^19
81-
};
82-
83-
#if (defined(__clang__) && (__clang__ < 6))
84-
# pragma clang diagnostic pop
85-
#endif
86-
87-
auto rit =
88-
coefficient_table.crbegin()
89-
+ static_cast<std::size_t>
90-
(
91-
(sizeof(T) == static_cast<std::size_t>(UINT8_C(4))) ? 4U : 0U
92-
);
93-
94-
result = *rit;
95-
9661
const auto xsq = x * x;
9762

98-
while(rit != coefficient_table.crend())
99-
{
100-
result = fma(result, xsq, *rit++);
101-
}
63+
result = detail::sinh_series_expansion(xsq);
10264

10365
result = x * fma(result, xsq, one);
10466
}

test/test_cosh.cpp

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ namespace local
272272
{
273273
using decimal_type = boost::decimal::decimal128;
274274

275-
using str_ctrl_array_type = std::array<const char*, 9U>;
275+
using str_ctrl_array_type = std::array<const char*, 19U>;
276276

277277
const str_ctrl_array_type ctrl_strings =
278278
{{
@@ -285,17 +285,17 @@ namespace local
285285
"1.22582183444686537963701508470572944",
286286
"1.31138966104807154082141166943546113",
287287
"1.41284130904939560893504431681606722",
288-
"1.53140558168565398981570176198960768"
289-
"1.66851855382225633267362743000999396"
290-
"1.82584096598945552946759518887583756"
291-
"2.00527833961335646927038567671483767"
292-
"2.20900405708350034304962730687406799"
293-
"2.43948568620755192849077658896354304"
294-
"2.69951486790030142594792594194283348"
295-
"2.99224112911281958915144028653782015"
296-
"3.32121003055092127036355857556155319"
297-
"3.69040611123595250949497414647005637"
298-
"4.10430115006125749566868477118593588"
288+
"1.53140558168565398981570176198960768",
289+
"1.66851855382225633267362743000999396",
290+
"1.82584096598945552946759518887583756",
291+
"2.00527833961335646927038567671483767",
292+
"2.20900405708350034304962730687406799",
293+
"2.43948568620755192849077658896354304",
294+
"2.69951486790030142594792594194283348",
295+
"2.99224112911281958915144028653782015",
296+
"3.32121003055092127036355857556155319",
297+
"3.69040611123595250949497414647005637",
298+
"4.10430115006125749566868477118593588",
299299
}};
300300

301301
std::array<decimal_type, std::tuple_size<str_ctrl_array_type>::value> cosh_values { };
@@ -325,9 +325,9 @@ namespace local
325325
from_chars(ctrl_strings[i], ctrl_strings[i] + std::strlen(ctrl_strings[i]), ctrl_values[i])
326326
);
327327

328-
const auto result_tgamma_is_ok = is_close_fraction(cosh_values[i], ctrl_values[i], my_tol);
328+
const auto result_cosh_is_ok = is_close_fraction(cosh_values[i], ctrl_values[i], my_tol);
329329

330-
result_is_ok = (result_tgamma_is_ok && result_is_ok);
330+
result_is_ok = (result_cosh_is_ok && result_is_ok);
331331
}
332332

333333
return result_is_ok;
@@ -367,6 +367,8 @@ auto main() -> int
367367

368368
BOOST_TEST(result_pos64_is_ok);
369369

370+
BOOST_TEST(result_pos128_is_ok);
371+
370372
result_is_ok = (result_pos_is_ok && result_is_ok);
371373
result_is_ok = (result_neg_is_ok && result_is_ok);
372374

0 commit comments

Comments
 (0)