Skip to content

Commit fa81b3c

Browse files
committed
Now use log10 to obtani the natural log()
1 parent d9c771b commit fa81b3c

File tree

3 files changed

+22
-44
lines changed

3 files changed

+22
-44
lines changed

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

Lines changed: 12 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#define BOOST_DECIMAL_DETAIL_CMATH_LOG_HPP
88

99
#include <boost/decimal/fwd.hpp> // NOLINT(llvm-include-order)
10-
#include <boost/decimal/detail/cmath/impl/log_impl.hpp>
1110
#include <boost/decimal/detail/concepts.hpp>
1211
#include <boost/decimal/detail/config.hpp>
1312
#include <boost/decimal/detail/type_traits.hpp>
@@ -27,18 +26,24 @@ template <typename T>
2726
constexpr auto log_impl(T x) noexcept
2827
BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T)
2928
{
30-
constexpr T zero { 0, 0 };
3129
constexpr T one { 1, 0 };
30+
constexpr T zero { 0, 0 };
3231

3332
T result { };
3433

35-
if (isnan(x))
34+
const auto fpc = fpclassify(x);
35+
36+
if (fpc == FP_ZERO)
37+
{
38+
result = -std::numeric_limits<T>::infinity();
39+
}
40+
else if (signbit(x) || (fpc == FP_NAN))
3641
{
37-
result = x;
42+
result = std::numeric_limits<T>::quiet_NaN();
3843
}
39-
else if (isinf(x))
44+
else if (fpc == FP_INFINITE)
4045
{
41-
result = (!signbit(x)) ? x: std::numeric_limits<T>::quiet_NaN();
46+
result = std::numeric_limits<T>::infinity();
4247
}
4348
else if (x < one)
4449
{
@@ -49,8 +54,6 @@ constexpr auto log_impl(T x) noexcept
4954
}
5055
else if ((x == zero) || (-x == zero))
5156
{
52-
// Actually, this should be equivalent to -HUGE_VAL.
53-
5457
result = -std::numeric_limits<T>::infinity();
5558
}
5659
else
@@ -60,32 +63,7 @@ constexpr auto log_impl(T x) noexcept
6063
}
6164
else if(x > one)
6265
{
63-
// The algorithm for 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-
67-
int exp2val { };
68-
69-
// TODO(ckormanyos) There is probably something more efficient than calling frexp here.
70-
auto g = frexp(x, &exp2val);
71-
72-
if (g < numbers::inv_sqrt2_v<T>)
73-
{
74-
g += g;
75-
76-
--exp2val;
77-
}
78-
79-
const auto s = (g - one) / (g + one);
80-
const auto z = s + s;
81-
const auto zsq = z * z;
82-
83-
result = z * fma(detail::log_series_expansion(zsq), zsq, one);
84-
85-
if (exp2val > 0)
86-
{
87-
result += static_cast<T>(exp2val * numbers::ln2_v<T>);
88-
}
66+
result = log10(x) * numbers::ln10_v<T>;
8967
}
9068
else
9169
{

test/test_log.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -452,9 +452,9 @@ auto main() -> int
452452
using decimal_type = boost::decimal::decimal32;
453453
using float_type = float;
454454

455-
const auto test_log_is_ok = local::test_log <decimal_type, float_type>(12);
456-
const auto test_log_between_1_and_2_is_ok = local::test_log_between_1_and_2<decimal_type, float_type>(24);
457-
const auto test_log_edge_is_ok = local::test_log_edge <decimal_type, float_type>(12);
455+
const auto test_log_is_ok = local::test_log <decimal_type, float_type>(32);
456+
const auto test_log_between_1_and_2_is_ok = local::test_log_between_1_and_2<decimal_type, float_type>(64);
457+
const auto test_log_edge_is_ok = local::test_log_edge <decimal_type, float_type>(32);
458458

459459
result_is_ok = (test_log_is_ok && test_log_between_1_and_2_is_ok && test_log_edge_is_ok && result_is_ok);
460460
}
@@ -463,9 +463,9 @@ auto main() -> int
463463
using decimal_type = boost::decimal::decimal64;
464464
using float_type = double;
465465

466-
const auto test_log_is_ok = local::test_log <decimal_type, float_type>(24);
467-
const auto test_log_between_1_and_2_is_ok = local::test_log_between_1_and_2<decimal_type, float_type>(256);
468-
const auto test_log_edge_is_ok = local::test_log_edge <decimal_type, float_type>(24);
466+
const auto test_log_is_ok = local::test_log <decimal_type, float_type>(64);
467+
const auto test_log_between_1_and_2_is_ok = local::test_log_between_1_and_2<decimal_type, float_type>(512);
468+
const auto test_log_edge_is_ok = local::test_log_edge <decimal_type, float_type>(64);
469469

470470
result_is_ok = (test_log_is_ok && test_log_between_1_and_2_is_ok && test_log_edge_is_ok && result_is_ok);
471471
}
@@ -479,7 +479,7 @@ auto main() -> int
479479
}
480480

481481
{
482-
const auto result_pos128_is_ok = local::test_log_128(1'400'000);
482+
const auto result_pos128_is_ok = local::test_log_128(800'000);
483483

484484
BOOST_TEST(result_pos128_is_ok);
485485

test/test_log10.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ auto main() -> int
373373
using decimal_type = boost::decimal::decimal32;
374374
using float_type = float;
375375

376-
const auto test_log10_is_ok = local::test_log10<decimal_type, float_type>(64);
376+
const auto test_log10_is_ok = local::test_log10<decimal_type, float_type>(128);
377377

378378
BOOST_TEST(test_log10_is_ok);
379379

@@ -384,7 +384,7 @@ auto main() -> int
384384
using decimal_type = boost::decimal::decimal64;
385385
using float_type = double;
386386

387-
const auto test_log10_is_ok = local::test_log10<decimal_type, float_type>(256);
387+
const auto test_log10_is_ok = local::test_log10<decimal_type, float_type>(512);
388388

389389
BOOST_TEST(test_log10_is_ok);
390390

@@ -414,7 +414,7 @@ auto main() -> int
414414
}
415415

416416
{
417-
const auto result_pos128_is_ok = local::test_log10_128(1'400'000);
417+
const auto result_pos128_is_ok = local::test_log10_128(600'000);
418418

419419
BOOST_TEST(result_pos128_is_ok);
420420

0 commit comments

Comments
 (0)