Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions include/boost/decimal/detail/cmath/acosh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <boost/decimal/fwd.hpp> // NOLINT(llvm-include-order)
#include <boost/decimal/detail/type_traits.hpp>
#include <boost/decimal/detail/cmath/fma.hpp>
#include <boost/decimal/detail/concepts.hpp>
#include <boost/decimal/numbers.hpp>

Expand Down Expand Up @@ -88,7 +89,7 @@ constexpr auto acosh_impl(const T x) noexcept
constexpr T sixty_three_over_2560 { T { 63, 0 } / T { 2560, 0 } };
constexpr T seventy_seven_over_4096 { T { 77, 0 } / T { 4096, 0 } };

result = ::boost::decimal::log(x) + numbers::ln2_v<T> - inv_xsq * fma(inv_xsq, fma(inv_xsq, fma(inv_xsq, fma(inv_xsq, fma(inv_xsq, seventy_seven_over_4096, sixty_three_over_2560), thirty_five_over_1024), five_over_96), three_over_32), one_fourth);
result = ::boost::decimal::log(x) + numbers::ln2_v<T> - inv_xsq * detail::unchecked_fma(inv_xsq, detail::unchecked_fma(inv_xsq, detail::unchecked_fma(inv_xsq, detail::unchecked_fma(inv_xsq, detail::unchecked_fma(inv_xsq, seventy_seven_over_4096, sixty_three_over_2560), thirty_five_over_1024), five_over_96), three_over_32), one_fourth);
}
else if (x < one_point_five)
{
Expand All @@ -97,12 +98,12 @@ constexpr auto acosh_impl(const T x) noexcept

const auto two_y = y + y;

result = ::boost::decimal::log1p(y + sqrt(fma(y, y, two_y)));
result = ::boost::decimal::log1p(y + sqrt(detail::unchecked_fma(y, y, two_y)));
}
else
{
// http://functions.wolfram.com/ElementaryFunctions/ArcCosh/02/
return(::boost::decimal::log(x + sqrt(fma(x, x, -one))));
return(::boost::decimal::log(x + sqrt(detail::unchecked_fma(x, x, -one))));
}
}
else
Expand All @@ -117,7 +118,7 @@ constexpr auto acosh_impl(const T x) noexcept
constexpr T six_thousand_four_hundred_thirty_five_over_71303168 { T { 6435, 0 } / T { 71303168, 0 } };

// approximation by Taylor series in y at 0 through order 8
result = sqrt(y + y) * fma(y, fma(y, fma(y, fma(y, fma(y, fma(y, fma(y, fma(y, six_thousand_four_hundred_thirty_five_over_71303168, four_hundred_twenty_nine_over_1966080), two_hundred_thirty_one_over_425984), sixty_three_over_90112), thirty_five_over_18432), five_over_896), three_over_160), one_twelfth), one);
result = sqrt(y + y) * detail::unchecked_fma(y, detail::unchecked_fma(y, detail::unchecked_fma(y, detail::unchecked_fma(y, detail::unchecked_fma(y, detail::unchecked_fma(y, detail::unchecked_fma(y, detail::unchecked_fma(y, six_thousand_four_hundred_thirty_five_over_71303168, four_hundred_twenty_nine_over_1966080), two_hundred_thirty_one_over_425984), sixty_three_over_90112), thirty_five_over_18432), five_over_896), three_over_160), one_twelfth), one);
}
}
else
Expand Down
5 changes: 3 additions & 2 deletions include/boost/decimal/detail/cmath/asinh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <boost/decimal/fwd.hpp> // NOLINT(llvm-include-order)
#include <boost/decimal/detail/type_traits.hpp>
#include <boost/decimal/detail/cmath/fma.hpp>
#include <boost/decimal/detail/concepts.hpp>
#include <boost/decimal/numbers.hpp>

Expand Down Expand Up @@ -63,7 +64,7 @@ constexpr auto asinh_impl(const T x) noexcept
constexpr T thirty_five_over_1024 { -T { 35, 0 } / T { 1024, 0 } };
constexpr T sixty_three_over_2560 { T { 63, 0 } / T { 2560, 0 } };

result = numbers::ln2_v<T> + ::boost::decimal::log(x) + inv_xsq * fma(inv_xsq, fma(inv_xsq, fma(inv_xsq, fma(inv_xsq, sixty_three_over_2560, thirty_five_over_1024), five_over_96), three_over_32), one_fourth);
result = numbers::ln2_v<T> + ::boost::decimal::log(x) + inv_xsq * detail::unchecked_fma(inv_xsq, detail::unchecked_fma(inv_xsq, detail::unchecked_fma(inv_xsq, detail::unchecked_fma(inv_xsq, sixty_three_over_2560, thirty_five_over_1024), five_over_96), three_over_32), one_fourth);
}
else if(x >= four_tenths)
{
Expand All @@ -88,7 +89,7 @@ constexpr auto asinh_impl(const T x) noexcept
constexpr T five_over_112 { -T { 5, 0 } / T { 112, 0 } };
constexpr T thirty_five_over_1152 { T { 35, 0 } / T { 1152, 0 } };

result = x * fma(xsq, fma(xsq, fma(xsq, fma(xsq, thirty_five_over_1152, five_over_112), three_over_40), one_sixth), one);
result = x * detail::unchecked_fma(xsq, detail::unchecked_fma(xsq, detail::unchecked_fma(xsq, detail::unchecked_fma(xsq, thirty_five_over_1152, five_over_112), three_over_40), one_sixth), one);
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion include/boost/decimal/detail/cmath/atanh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <boost/decimal/fwd.hpp> // NOLINT(llvm-include-order)
#include <boost/decimal/detail/type_traits.hpp>
#include <boost/decimal/detail/cmath/fma.hpp>
#include <boost/decimal/detail/concepts.hpp>
#include <boost/decimal/detail/config.hpp>

Expand Down Expand Up @@ -82,7 +83,7 @@ constexpr auto atanh_impl(const T x) noexcept
constexpr T one_seventh { one / T { 7, 0 } };
constexpr T one_ninth { one / T { 9, 0 } };

result = xx * fma(xsq, fma(xsq, fma(xsq, fma(xsq, one_ninth, one_seventh), one_fifth), one_third), one);
result = xx * unchecked_fma(xsq, unchecked_fma(xsq, unchecked_fma(xsq, unchecked_fma(xsq, one_ninth, one_seventh), one_fifth), one_third), one);
}

if (b_neg) { result = -result; }
Expand Down
2 changes: 1 addition & 1 deletion include/boost/decimal/detail/cmath/log.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ constexpr auto log_impl(const T x) noexcept
else if (x < one)
{
// Handle reflection.
result = -::boost::decimal::log(one / x);
result = -log10(one / x) * numbers::ln10_v<T>;
}
else if(x > one)
{
Expand Down
3 changes: 2 additions & 1 deletion include/boost/decimal/detail/cmath/log10.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <boost/decimal/fwd.hpp> // NOLINT(llvm-include-order)
#include <boost/decimal/detail/cmath/impl/log_impl.hpp>
#include <boost/decimal/detail/cmath/fma.hpp>
#include <boost/decimal/detail/cmath/log1p.hpp>
#include <boost/decimal/detail/concepts.hpp>
#include <boost/decimal/detail/config.hpp>
Expand Down Expand Up @@ -117,7 +118,7 @@ constexpr auto log10_impl(const T x) noexcept
const T z { s + s };
const T zsq { z * z };

result = z * fma(detail::log_series_expansion(zsq), zsq, one);
result = z * detail::unchecked_fma(detail::log_series_expansion(zsq), zsq, one);

result /= numbers::ln10_v<T>;

Expand Down
27 changes: 4 additions & 23 deletions test/test_acosh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,6 @@ auto my_one () -> boost::decimal::decimal32_t&;

namespace local
{
template<typename IntegralTimePointType,
typename ClockType = std::chrono::high_resolution_clock>
auto time_point() noexcept -> IntegralTimePointType
{
using local_integral_time_point_type = IntegralTimePointType;
using local_clock_type = ClockType;

const auto current_now =
static_cast<std::uintmax_t>
(
std::chrono::duration_cast<std::chrono::nanoseconds>
(
local_clock_type::now().time_since_epoch()
).count()
);

return static_cast<local_integral_time_point_type>(current_now);
}

template<typename NumericType>
auto is_close_fraction(const NumericType& a,
const NumericType& b,
Expand Down Expand Up @@ -77,7 +58,7 @@ namespace local
// Use a pseudo-random seed value.
std::mt19937_64 gen(std::random_device{}());

gen.seed(time_point<typename std::mt19937_64::result_type>());
gen.seed(static_cast<typename std::mt19937_64::result_type>(42));

auto dis =
std::uniform_real_distribution<float>
Expand Down Expand Up @@ -371,9 +352,9 @@ auto main() -> int
{
auto result_is_ok = true;

const auto result_small_is_ok = local::test_acosh(INT32_C(32), 1.2L, 1.60L);
const auto result_medium_is_ok = local::test_acosh(INT32_C(16), 1.59L, 10.1L);
const auto result_large_is_ok = local::test_acosh(INT32_C(16), 1.0E+01L, 1.0E+26L);
const auto result_small_is_ok = local::test_acosh(INT32_C(32), 1.2L, 1.60L); // High tolerance due to float conversion for comparison.
const auto result_medium_is_ok = local::test_acosh(INT32_C(16), 1.59L, 10.1L); // High tolerance due to float conversion for comparison.
const auto result_large_is_ok = local::test_acosh(INT32_C(16), 1.0E+01L, 1.0E+26L); // High tolerance due to float conversion for comparison.

BOOST_TEST(result_small_is_ok);
BOOST_TEST(result_medium_is_ok);
Expand Down
29 changes: 5 additions & 24 deletions test/test_asinh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,6 @@ auto my_zero() -> boost::decimal::decimal32_t&;

namespace local
{
template<typename IntegralTimePointType,
typename ClockType = std::chrono::high_resolution_clock>
auto time_point() noexcept -> IntegralTimePointType
{
using local_integral_time_point_type = IntegralTimePointType;
using local_clock_type = ClockType;

const auto current_now =
static_cast<std::uintmax_t>
(
std::chrono::duration_cast<std::chrono::nanoseconds>
(
local_clock_type::now().time_since_epoch()
).count()
);

return static_cast<local_integral_time_point_type>(current_now);
}

template<typename NumericType>
auto is_close_fraction(const NumericType& a,
const NumericType& b,
Expand Down Expand Up @@ -75,7 +56,7 @@ namespace local

std::mt19937_64 gen(std::random_device{}());

gen.seed(time_point<typename std::mt19937_64::result_type>());
gen.seed(static_cast<typename std::mt19937_64::result_type>(42));

auto dis =
std::uniform_real_distribution<float>
Expand Down Expand Up @@ -385,10 +366,10 @@ auto main() -> int
{
auto result_is_ok = true;

const auto result_tiny_is_ok = local::test_asinh(INT32_C(48), false, 1.001, 1.1); // High tolerance due to float conversion for comparison.
const auto result_small_is_ok = local::test_asinh(INT32_C(48), false, 0.1, 1.59); // High tolerance due to float conversion for comparison.
const auto result_small_neg_is_ok = local::test_asinh(INT32_C(48), true, 0.1, 1.59); // High tolerance due to float conversion for comparison.
const auto result_large_is_ok = local::test_asinh(INT32_C(48), false, 1.0E+01, 1.0E+19); // High tolerance due to float conversion for comparison.
const auto result_tiny_is_ok = local::test_asinh(INT32_C(48), false, 1.001, 1.1); // High tolerance due to float conversion for comparison.
const auto result_small_is_ok = local::test_asinh(INT32_C(32), false, 0.1, 1.59); // High tolerance due to float conversion for comparison.
const auto result_small_neg_is_ok = local::test_asinh(INT32_C(32), true, 0.1, 1.59); // High tolerance due to float conversion for comparison.
const auto result_large_is_ok = local::test_asinh(INT32_C(16), false, 1.0E+01, 1.0E+19); // High tolerance due to float conversion for comparison.

BOOST_TEST(result_tiny_is_ok);
BOOST_TEST(result_small_is_ok);
Expand Down
35 changes: 8 additions & 27 deletions test/test_atanh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,6 @@ auto my_one () -> boost::decimal::decimal32_t&;

namespace local
{
template<typename IntegralTimePointType,
typename ClockType = std::chrono::high_resolution_clock>
auto time_point() noexcept -> IntegralTimePointType
{
using local_integral_time_point_type = IntegralTimePointType;
using local_clock_type = ClockType;

const auto current_now =
static_cast<std::uintmax_t>
(
std::chrono::duration_cast<std::chrono::nanoseconds>
(
local_clock_type::now().time_since_epoch()
).count()
);

return static_cast<local_integral_time_point_type>(current_now);
}

template<typename NumericType>
auto is_close_fraction(const NumericType& a,
const NumericType& b,
Expand Down Expand Up @@ -77,7 +58,7 @@ namespace local
std::random_device rd;
std::mt19937_64 gen(rd());

gen.seed(time_point<typename std::mt19937_64::result_type>());
gen.seed(static_cast<typename std::mt19937_64::result_type>(42));

auto dis =
std::uniform_real_distribution<float>
Expand Down Expand Up @@ -298,7 +279,7 @@ auto main() -> int
const auto result_eps_is_ok =
local::test_atanh
(
INT32_C(128),
INT32_C(128), // High tolerance due to float conversion for comparison.
false,
static_cast<float>(static_cast<double>(fourth_root_epsilon) / 32.0),
static_cast<float>(static_cast<double>(fourth_root_epsilon) * 32.0)
Expand All @@ -307,15 +288,15 @@ auto main() -> int
const auto result_eps_near_one_is_ok =
local::test_atanh
(
INT32_C(256),
INT32_C(128), // High tolerance due to float conversion for comparison.
false,
static_cast<float>(static_cast<long double>( static_cast<float>(1.0L) - static_cast<float>(static_cast<double>(fourth_root_epsilon) * 32.0L))),
static_cast<float>(static_cast<long double>( static_cast<float>(1.0L) - static_cast<float>(static_cast<double>(fourth_root_epsilon) / 32.0L)))
static_cast<float>(1.0L) - static_cast<float>(static_cast<double>(fourth_root_epsilon) * 32.0L),
static_cast<float>(1.0L) - static_cast<float>(static_cast<double>(fourth_root_epsilon) / 32.0L)
);

const auto result_tiny_is_ok = local::test_atanh(INT32_C(96), false, 0.001, 0.1);
const auto result_medium_is_ok = local::test_atanh(INT32_C(96), true, 0.1, 0.9);
const auto result_medium_neg_is_ok = local::test_atanh(INT32_C(96), false, 0.1, 0.9);
const auto result_tiny_is_ok = local::test_atanh(INT32_C(48), false, 0.001, 0.1); // High tolerance due to float conversion for comparison.
const auto result_medium_is_ok = local::test_atanh(INT32_C(48), true, 0.1, 0.9); // High tolerance due to float conversion for comparison.
const auto result_medium_neg_is_ok = local::test_atanh(INT32_C(48), false, 0.1, 0.9); // High tolerance due to float conversion for comparison.

BOOST_TEST(result_eps_is_ok);
BOOST_TEST(result_eps_near_one_is_ok);
Expand Down
Loading
Loading