Skip to content

Commit edf3757

Browse files
committed
Retry CI but pow-of-10 loop still present
1 parent afc7f3f commit edf3757

File tree

2 files changed

+67
-56
lines changed

2 files changed

+67
-56
lines changed

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

Lines changed: 52 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -40,85 +40,84 @@ constexpr auto log10_impl(T x) noexcept
4040
{
4141
result = (!signbit(x)) ? x: std::numeric_limits<T>::quiet_NaN();
4242
}
43-
else if (x < one)
44-
{
45-
// Handle reflection, the [+/-] zero-pole, and non-pole, negative x.
46-
if (x > zero)
47-
{
48-
result = -log10(one / x);
49-
}
50-
else if ((x == zero) || (-x == zero))
51-
{
52-
// Actually, this should be equivalent to -HUGE_VAL.
53-
54-
result = -std::numeric_limits<T>::infinity();
55-
}
56-
else
57-
{
58-
result = std::numeric_limits<T>::quiet_NaN();
59-
}
60-
}
61-
else if(x > one)
43+
else
6244
{
63-
// The algorithm for base-10 logarithm is based on Chapter 5, pages 35-36
64-
// of Cody and Waite, Software Manual for the Elementary Functions,
65-
// Prentice Hall, 1980.
66-
6745
int exp10val { };
6846

6947
T g { frexp10(x, &exp10val) };
7048

7149
while(g > one)
7250
{
73-
// TODO(ckormanyos) Do we really have to multiply individual powers
74-
// of 10 here? Or is there a reliable way to simply use pow10()?
75-
// For instance count intagral orders of exp10val and divide by pow10().
76-
77-
g /= 10;
51+
g /= 10;
7852

79-
++exp10val;
53+
++exp10val;
8054
}
8155

82-
if(g == one)
56+
const bool is_pure = (g == one);
57+
58+
if(is_pure)
8359
{
8460
result = T { exp10val };
8561
}
8662
else
8763
{
88-
constexpr T inv_sqrt10 { UINT64_C(3162277660168379332), -19 };
64+
if (x < one)
65+
{
66+
// Handle reflection, the [+/-] zero-pole, and non-pole, negative x.
67+
if (x > zero)
68+
{
69+
result = -log10(one / x);
70+
}
71+
else if ((x == zero) || (-x == zero))
72+
{
73+
// Actually, this should be equivalent to -HUGE_VAL.
74+
75+
result = -std::numeric_limits<T>::infinity();
76+
}
77+
else
78+
{
79+
result = std::numeric_limits<T>::quiet_NaN();
80+
}
81+
}
82+
else if(x > one)
83+
{
84+
// The algorithm for base-10 logarithm is based on Chapter 5, pages 35-36
85+
// of Cody and Waite, Software Manual for the Elementary Functions,
86+
// Prentice Hall, 1980.
87+
constexpr T inv_sqrt10 { UINT64_C(3162277660168379332), -19 };
8988

90-
const bool reduce_sqrt10 { g < inv_sqrt10 };
89+
const bool reduce_sqrt10 { g < inv_sqrt10 };
9190

92-
if (reduce_sqrt10)
93-
{
94-
constexpr T sqrt10 { UINT64_C(3162277660168379332), -18 };
91+
if (reduce_sqrt10)
92+
{
93+
constexpr T sqrt10 { UINT64_C(3162277660168379332), -18 };
9594

96-
g *= sqrt10;
97-
}
95+
g *= sqrt10;
96+
}
9897

99-
const T s { (g - one) / (g + one) };
100-
const T z { s + s };
101-
const T zsq { z * z };
98+
const T s { (g - one) / (g + one) };
99+
const T z { s + s };
100+
const T zsq { z * z };
102101

103-
result = z * fma(detail::log_series_expansion(zsq), zsq, one);
102+
result = z * fma(detail::log_series_expansion(zsq), zsq, one);
104103

105-
result /= numbers::ln10_v<T>;
104+
result /= numbers::ln10_v<T>;
106105

107-
if(reduce_sqrt10)
108-
{
109-
constexpr T half { 5, -1 };
106+
if(reduce_sqrt10)
107+
{
108+
constexpr T half { 5, -1 };
110109

111-
result -= half;
112-
}
110+
result -= half;
111+
}
113112

114-
result += static_cast<T>(exp10val);
113+
result += static_cast<T>(exp10val);
114+
}
115+
else
116+
{
117+
result = zero;
118+
}
115119
}
116120
}
117-
else
118-
{
119-
result = zero;
120-
}
121-
122121
return result;
123122
}
124123

test/test_log10.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ namespace local
156156
}
157157

158158
template<typename DecimalType, typename FloatType>
159-
auto test_log10_pow10(const int tol_factor) -> bool
159+
auto test_log10_pow10() -> bool
160160
{
161161
using decimal_type = DecimalType;
162162
using float_type = FloatType;
@@ -167,9 +167,12 @@ namespace local
167167
{
168168
const decimal_type x_arg { 1, i };
169169

170-
const decimal_type log_val_p10 = log10(x_arg);
170+
const decimal_type val_dec = log10(x_arg);
171+
const float_type val_ctrl = static_cast<float_type>(i);
171172

172-
const auto result_log10_pow10_is_ok = (static_cast<float_type>(log_val_p10) == static_cast<float_type>(i));
173+
const float_type val_to_check = static_cast<float_type>(val_dec);
174+
175+
const auto result_log10_pow10_is_ok = (val_to_check == val_ctrl);
173176

174177
result_is_ok = (result_log10_pow10_is_ok && result_is_ok);
175178
}
@@ -194,6 +197,15 @@ auto main() -> int
194197
result_is_ok = (test_log10_is_ok && result_is_ok);
195198
}
196199

200+
{
201+
using decimal_type = boost::decimal::decimal32;
202+
using float_type = float;
203+
204+
const auto test_log10_pow10_is_ok = local::test_log10_pow10<decimal_type, float_type>();
205+
206+
result_is_ok = (test_log10_pow10_is_ok && result_is_ok);
207+
}
208+
197209
result_is_ok = ((boost::report_errors() == 0) && result_is_ok);
198210

199211
return (result_is_ok ? 0 : -1);

0 commit comments

Comments
 (0)