Skip to content

Commit 23f5439

Browse files
committed
Merge branch 'develop' into log10
2 parents 6c1d551 + 6820459 commit 23f5439

File tree

8 files changed

+297
-26
lines changed

8 files changed

+297
-26
lines changed

.drone.jsonnet

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,16 +187,58 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
187187
),
188188

189189
linux_pipeline(
190-
"Linux 18.04 GCC 7* 32",
190+
"Linux 18.04 GCC 7* 32 03",
191191
"cppalliance/droneubuntu1804:1",
192-
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17', ADDRMD: '32' },
192+
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03', ADDRMD: '32' },
193193
"nload",
194194
),
195195

196196
linux_pipeline(
197-
"Linux 18.04 GCC 7* 64",
197+
"Linux 18.04 GCC 7* 32 11",
198198
"cppalliance/droneubuntu1804:1",
199-
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17', ADDRMD: '64' },
199+
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11', ADDRMD: '32' },
200+
"nload",
201+
),
202+
203+
linux_pipeline(
204+
"Linux 18.04 GCC 7* 32 14",
205+
"cppalliance/droneubuntu1804:1",
206+
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '14', ADDRMD: '32' },
207+
"nload",
208+
),
209+
210+
linux_pipeline(
211+
"Linux 18.04 GCC 7* 32 17",
212+
"cppalliance/droneubuntu1804:1",
213+
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '17', ADDRMD: '32' },
214+
"nload",
215+
),
216+
217+
linux_pipeline(
218+
"Linux 18.04 GCC 7* 64 03",
219+
"cppalliance/droneubuntu1804:1",
220+
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03', ADDRMD: '64' },
221+
"nload",
222+
),
223+
224+
linux_pipeline(
225+
"Linux 18.04 GCC 7* 64 11",
226+
"cppalliance/droneubuntu1804:1",
227+
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11', ADDRMD: '64' },
228+
"nload",
229+
),
230+
231+
linux_pipeline(
232+
"Linux 18.04 GCC 7* 64 14",
233+
"cppalliance/droneubuntu1804:1",
234+
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '14', ADDRMD: '64' },
235+
"nload",
236+
),
237+
238+
linux_pipeline(
239+
"Linux 18.04 GCC 7* 64 17",
240+
"cppalliance/droneubuntu1804:1",
241+
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '17', ADDRMD: '64' },
200242
"nload",
201243
),
202244

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

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121
namespace boost {
2222
namespace decimal {
2323

24-
BOOST_DECIMAL_EXPORT template <typename T>
25-
constexpr auto log(T x) noexcept
24+
namespace detail {
25+
26+
template <typename T>
27+
constexpr auto log_impl(T x) noexcept
2628
BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T)
2729
{
2830
constexpr T zero { 0, 0 };
@@ -93,6 +95,29 @@ constexpr auto log(T x) noexcept
9395
return result;
9496
}
9597

98+
} //namespace detail
99+
100+
BOOST_DECIMAL_EXPORT template <typename T>
101+
constexpr auto log(T x) noexcept
102+
BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T)
103+
{
104+
#if BOOST_DECIMAL_DEC_EVAL_METHOD == 0
105+
106+
using evaluation_type = T;
107+
108+
#elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1
109+
110+
using evaluation_type = detail::promote_args_t<T, decimal64>;
111+
112+
#else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2
113+
114+
using evaluation_type = detail::promote_args_t<T, decimal128>;
115+
116+
#endif
117+
118+
return static_cast<T>(detail::log_impl(static_cast<evaluation_type>(x)));
119+
}
120+
96121
} // namespace decimal
97122
} // namespace boost
98123

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

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121
namespace boost {
2222
namespace decimal {
2323

24-
BOOST_DECIMAL_EXPORT template <typename T>
25-
constexpr auto log1p(T x) noexcept
24+
namespace detail {
25+
26+
template <typename T>
27+
constexpr auto log1p_impl(T x) noexcept
2628
BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T)
2729
{
2830
constexpr T one { 1, 0 };
@@ -64,6 +66,29 @@ constexpr auto log1p(T x) noexcept
6466
return result;
6567
}
6668

69+
} // namespace detail
70+
71+
BOOST_DECIMAL_EXPORT template <typename T>
72+
constexpr auto log1p(T x) noexcept
73+
BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T)
74+
{
75+
#if BOOST_DECIMAL_DEC_EVAL_METHOD == 0
76+
77+
using evaluation_type = T;
78+
79+
#elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1
80+
81+
using evaluation_type = detail::promote_args_t<T, decimal64>;
82+
83+
#else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2
84+
85+
using evaluation_type = detail::promote_args_t<T, decimal128>;
86+
87+
#endif
88+
89+
return static_cast<T>(detail::log1p_impl(static_cast<evaluation_type>(x)));
90+
}
91+
6792
} // namespace decimal
6893
} // namespace boost
6994

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

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121
namespace boost {
2222
namespace decimal {
2323

24-
BOOST_DECIMAL_EXPORT template <typename T>
25-
constexpr auto sinh(T x) noexcept
24+
namespace detail {
25+
26+
template <typename T>
27+
constexpr auto sinh_impl(T x) noexcept
2628
BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T)
2729
{
2830
const auto fpc = fpclassify(x);
@@ -78,6 +80,29 @@ constexpr auto sinh(T x) noexcept
7880
return result;
7981
}
8082

83+
} // namespace detail
84+
85+
BOOST_DECIMAL_EXPORT template <typename T>
86+
constexpr auto sinh(T x) noexcept
87+
BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T)
88+
{
89+
#if BOOST_DECIMAL_DEC_EVAL_METHOD == 0
90+
91+
using evaluation_type = T;
92+
93+
#elif BOOST_DECIMAL_DEC_EVAL_METHOD == 1
94+
95+
using evaluation_type = detail::promote_args_t<T, decimal64>;
96+
97+
#else // BOOST_DECIMAL_DEC_EVAL_METHOD == 2
98+
99+
using evaluation_type = detail::promote_args_t<T, decimal128>;
100+
101+
#endif
102+
103+
return static_cast<T>(detail::sinh_impl(static_cast<evaluation_type>(x)));
104+
}
105+
81106
} // namespace decimal
82107
} // namespace boost
83108

include/boost/decimal/detail/remove_trailing_zeros.hpp

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,13 @@ constexpr auto remove_trailing_zeros(std::uint32_t n) noexcept -> remove_trailin
4040
{
4141
std::size_t s {};
4242

43-
auto r = rotr<32>(n * UINT32_C(184254097), 4);
44-
auto b = r < UINT32_C(429497);
43+
auto r = rotr<32>(n * UINT32_C(15273505), 8);
44+
auto b = r < UINT32_C(43);
45+
s = s * 2U + static_cast<std::size_t>(b);
46+
n = b ? r : n;
47+
48+
r = rotr<32>(n * UINT32_C(184254097), 4);
49+
b = r < UINT32_C(429497);
4550
s = s * 2U + static_cast<std::size_t>(b);
4651
n = b ? r : n;
4752

@@ -62,8 +67,13 @@ constexpr auto remove_trailing_zeros(std::uint64_t n) noexcept -> remove_trailin
6267
{
6368
std::size_t s {};
6469

65-
auto r = rotr<64>(n * UINT64_C(28999941890838049), 8);
66-
auto b = r < UINT64_C(184467440738);
70+
auto r = rotr<64>(n * UINT64_C(230079197716545), 16);
71+
auto b = r < UINT64_C(1845);
72+
s = s * 2U + static_cast<std::size_t>(b);
73+
n = b ? r : n;
74+
75+
r = rotr<64>(n * UINT64_C(28999941890838049), 8);
76+
b = r < UINT64_C(184467440738);
6777
s = s * 2U + static_cast<std::size_t>(b);
6878
n = b ? r : n;
6979

@@ -85,22 +95,39 @@ constexpr auto remove_trailing_zeros(std::uint64_t n) noexcept -> remove_trailin
8595
return {n, s};
8696
}
8797

88-
// TODO(mborland): Make this better for the 2-word case
8998
constexpr auto remove_trailing_zeros(uint128 n) noexcept -> remove_trailing_zeros_return<uint128>
9099
{
91-
if (n.high == UINT64_C(0))
92-
{
93-
const auto temp {remove_trailing_zeros(n.low)};
94-
return {static_cast<uint128>(temp.trimmed_number), temp.number_of_removed_zeros};
95-
}
96-
97100
std::size_t s {};
98101

99-
while (n % 10 == 0)
100-
{
101-
n /= 10;
102-
++s;
103-
}
102+
auto r = rotr<128>(n * uint128(UINT64_C(0x62B42691AD836EB1), UINT64_C(0x16590F420A835081)), 32);
103+
auto b = r < uint128 {UINT64_C(0x0), UINT64_C(0x33EC48)};
104+
s = s * 2U + static_cast<std::size_t>(b);
105+
n = b ? r : n;
106+
107+
r = rotr<128>(n * uint128 {UINT64_C(0x3275305C1066), UINT64_C(0xE4A4D1417CD9A041)}, 16);
108+
b = r < uint128 {UINT64_C(0x734), UINT64_C(0xACA5F6226F0ADA62)};
109+
s = s * 2U + static_cast<std::size_t>(b);
110+
n = b ? r : n;
111+
112+
r = rotr<128>(n * uint128 {UINT64_C(0x6B7213EE9F5A78), UINT64_C(0xC767074B22E90E21)}, 8);
113+
b = r < uint128 {UINT64_C(0x2AF31DC461), UINT64_C(0x1873BF3F70834ACE)};
114+
s = s * 2U + static_cast<std::size_t>(b);
115+
n = b ? r : n;
116+
117+
r = rotr<128>(n * uint128 {UINT64_C(0x95182A9930BE0DE), UINT64_C(0xD288CE703AFB7E91)}, 4);
118+
b = r < uint128 {UINT64_C(0x68DB8BAC710CB), UINT64_C(0x295E9E1B089A0276)};
119+
s = s * 2U + static_cast<std::size_t>(b);
120+
n = b ? r : n;
121+
122+
r = rotr<128>(n * uint128 {UINT64_C(0x28F5C28F5C28F5C2), UINT64_C(0x8F5C28F5C28F5C29)}, 2);
123+
b = r < uint128 {UINT64_C(0x28F5C28F5C28F5C), UINT64_C(0x28F5C28F5C28F5C3)};
124+
s = s * 2U + static_cast<std::size_t>(b);
125+
n = b ? r : n;
126+
127+
r = rotr<128>(n * uint128 {UINT64_C(0xCCCCCCCCCCCCCCCC), UINT64_C(0xCCCCCCCCCCCCCCCD)}, 1);
128+
b = r < uint128 {UINT64_C(0x1999999999999999), UINT64_C(0x999999999999999A)};
129+
s = s * 2U + static_cast<std::size_t>(b);
130+
n = b ? r : n;
104131

105132
return {n, s};
106133
}

test/Jamfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ run test_log1p.cpp ;
110110
run test_pow.cpp ;
111111
run test_promotion.cpp ;
112112
run test_remainder_remquo.cpp ;
113+
run test_remove_trailing_zeros.cpp ;
113114
run test_sin_cos.cpp ;
114115
run test_sinh.cpp ;
115116
run test_snprintf.cpp ;
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// Copyright 2024 Matt Borland
2+
// Distributed under the Boost Software License, Version 1.0.
3+
// https://www.boost.org/LICENSE_1_0.txt
4+
5+
#include <boost/decimal.hpp>
6+
#include <boost/core/lightweight_test.hpp>
7+
#include <array>
8+
#include <limits>
9+
#include <cstdint>
10+
11+
template <typename T>
12+
void test()
13+
{
14+
constexpr std::array<std::uint64_t, 20> powers_of_10 =
15+
{{
16+
UINT64_C(1), UINT64_C(10), UINT64_C(100), UINT64_C(1000), UINT64_C(10000), UINT64_C(100000), UINT64_C(1000000),
17+
UINT64_C(10000000), UINT64_C(100000000), UINT64_C(1000000000), UINT64_C(10000000000), UINT64_C(100000000000),
18+
UINT64_C(1000000000000), UINT64_C(10000000000000), UINT64_C(100000000000000), UINT64_C(1000000000000000),
19+
UINT64_C(10000000000000000), UINT64_C(100000000000000000), UINT64_C(1000000000000000000), UINT64_C(10000000000000000000)
20+
}};
21+
22+
for (const auto& val : powers_of_10)
23+
{
24+
if (val < std::numeric_limits<T>::max())
25+
{
26+
const auto temp {boost::decimal::detail::remove_trailing_zeros(static_cast<T>(val))};
27+
if (!BOOST_TEST_EQ(temp.trimmed_number, T(1)))
28+
{
29+
// LCOV_EXCL_START
30+
std::cerr << "Input Number: " << val
31+
<< "\nOutput Number: " << temp.trimmed_number
32+
<< "\nZeros removed: " << temp.number_of_removed_zeros << std::endl;
33+
// LCOV_EXCL_STOP
34+
}
35+
}
36+
}
37+
}
38+
39+
void test_extended()
40+
{
41+
using namespace boost::decimal;
42+
constexpr std::array<detail::uint128, 18> powers_of_10 =
43+
{{
44+
detail::uint128 {UINT64_C(0x5), UINT64_C(0x6BC75E2D63100000)},
45+
detail::uint128 {UINT64_C(0x36), UINT64_C(0x35C9ADC5DEA00000)},
46+
detail::uint128 {UINT64_C(0x21E), UINT64_C(0x19E0C9BAB2400000)},
47+
detail::uint128 {UINT64_C(0x152D), UINT64_C(0x02C7E14AF6800000)},
48+
detail::uint128 {UINT64_C(0x84595), UINT64_C(0x161401484A000000)},
49+
detail::uint128 {UINT64_C(0x52B7D2), UINT64_C(0xDCC80CD2E4000000)},
50+
detail::uint128 {UINT64_C(0x33B2E3C), UINT64_C(0x9FD0803CE8000000)},
51+
detail::uint128 {UINT64_C(0x204FCE5E), UINT64_C(0x3E25026110000000)},
52+
detail::uint128 {UINT64_C(0x1431E0FAE), UINT64_C(0x6D7217CAA0000000)},
53+
detail::uint128 {UINT64_C(0xC9F2C9CD0), UINT64_C(0x4674EDEA40000000)},
54+
detail::uint128 {UINT64_C(0x7E37BE2022), UINT64_C(0xC0914B2680000000)},
55+
detail::uint128 {UINT64_C(0x4EE2D6D415B), UINT64_C(0x85ACEF8100000000)},
56+
detail::uint128 {UINT64_C(0x314DC6448D93), UINT64_C(0x38C15B0A00000000)},
57+
detail::uint128 {UINT64_C(0x1ED09BEAD87C0), UINT64_C(0x378D8E6400000000)},
58+
detail::uint128 {UINT64_C(0x13426172C74D82), UINT64_C(0x2B878FE800000000)},
59+
detail::uint128 {UINT64_C(0xC097CE7BC90715), UINT64_C(0xB34B9F1000000000)},
60+
detail::uint128 {UINT64_C(0x785EE10D5DA46D9), UINT64_C(0x00F436A000000000)},
61+
detail::uint128 {UINT64_C(0x4B3B4CA85A86C47A), UINT64_C(0x098A224000000000)}
62+
}};
63+
64+
for (const auto& val : powers_of_10)
65+
{
66+
const auto temp {boost::decimal::detail::remove_trailing_zeros(val)};
67+
if (!BOOST_TEST_EQ(temp.trimmed_number, detail::uint128(1)))
68+
{
69+
// LCOV_EXCL_START
70+
std::cerr << "Input Number: " << val
71+
<< "\nOutput Number: " << temp.trimmed_number
72+
<< "\nZeros removed: " << temp.number_of_removed_zeros << std::endl;
73+
// LCOV_EXCL_STOP
74+
}
75+
}
76+
}
77+
78+
int main()
79+
{
80+
test<std::uint32_t>();
81+
test<std::uint64_t>();
82+
test<boost::decimal::detail::uint128>();
83+
84+
test_extended();
85+
86+
return boost::report_errors();
87+
}

0 commit comments

Comments
 (0)