mirror of
https://github.com/boostorg/multiprecision.git
synced 2026-02-27 17:12:26 +00:00
Test and fix mixed precision arithmetic with component types.
This commit is contained in:
@@ -52,7 +52,7 @@ namespace boost {
|
||||
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value, number<B, et_off> >::type
|
||||
operator+(const number<B, et_off>& a, const V& b)
|
||||
{
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a);
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_add;
|
||||
eval_add(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
|
||||
@@ -62,7 +62,7 @@ namespace boost {
|
||||
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && !is_equivalent_number_type<V, B>::value, number<B, et_off> >::type
|
||||
operator+(const V& a, const number<B, et_off>& b)
|
||||
{
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(b);
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(b, a);
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_add;
|
||||
eval_add(result.backend(), b.backend(), number<B, et_off>::canonical_value(a));
|
||||
@@ -84,7 +84,7 @@ namespace boost {
|
||||
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value, number<B, et_off> >::type
|
||||
operator-(const number<B, et_off>& a, const V& b)
|
||||
{
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a);
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_subtract;
|
||||
eval_subtract(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
|
||||
@@ -94,7 +94,7 @@ namespace boost {
|
||||
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && !is_equivalent_number_type<V, B>::value, number<B, et_off> >::type
|
||||
operator-(const V& a, const number<B, et_off>& b)
|
||||
{
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(b);
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(b, a);
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_subtract;
|
||||
eval_subtract(result.backend(), number<B, et_off>::canonical_value(a), b.backend());
|
||||
@@ -116,7 +116,7 @@ namespace boost {
|
||||
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value, number<B, et_off> >::type
|
||||
operator*(const number<B, et_off>& a, const V& b)
|
||||
{
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a);
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_multiply;
|
||||
eval_multiply(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
|
||||
@@ -126,7 +126,7 @@ namespace boost {
|
||||
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && !is_equivalent_number_type<V, B>::value, number<B, et_off> >::type
|
||||
operator*(const V& a, const number<B, et_off>& b)
|
||||
{
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(b);
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(b, a);
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_multiply;
|
||||
eval_multiply(result.backend(), b.backend(), number<B, et_off>::canonical_value(a));
|
||||
@@ -148,7 +148,7 @@ namespace boost {
|
||||
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value, number<B, et_off> >::type
|
||||
operator/(const number<B, et_off>& a, const V& b)
|
||||
{
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a);
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_divide;
|
||||
eval_divide(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
|
||||
@@ -158,7 +158,7 @@ namespace boost {
|
||||
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && !is_equivalent_number_type<V, B>::value, number<B, et_off> >::type
|
||||
operator/(const V& a, const number<B, et_off>& b)
|
||||
{
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(b);
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(b, a);
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_divide;
|
||||
eval_divide(result.backend(), number<B, et_off>::canonical_value(a), b.backend());
|
||||
|
||||
@@ -197,6 +197,20 @@ inline BOOST_MP_CXX14_CONSTEXPR void maybe_promote_precision(T* obj)
|
||||
#define BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(T) if (boost::multiprecision::detail::is_variable_precision<T>::value)
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
struct scoped_target_precision
|
||||
{
|
||||
variable_precision_options opts;
|
||||
scoped_target_precision() : opts(T::thread_default_variable_precision_options())
|
||||
{
|
||||
T::thread_default_variable_precision_options(variable_precision_options::preserve_target_precision, variable_precision_options::precision_group);
|
||||
}
|
||||
~scoped_target_precision()
|
||||
{
|
||||
T::thread_default_variable_precision_options(opts);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
} // namespace boost::multiprecision::detail
|
||||
|
||||
@@ -562,7 +562,7 @@ struct mpc_complex_backend<0> : public detail::mpc_complex_imp<0>
|
||||
}
|
||||
template <unsigned D>
|
||||
mpc_complex_backend(const mpfr_float_backend<D>& val)
|
||||
: detail::mpc_complex_imp<0>(mpfr_get_prec(val.data()))
|
||||
: detail::mpc_complex_imp<0>(this->preserve_source_precision() ? mpfr_get_prec(val.data()) : multiprecision::detail::digits10_2_2(this->get_default_precision()))
|
||||
{
|
||||
mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
|
||||
}
|
||||
@@ -707,7 +707,8 @@ struct mpc_complex_backend<0> : public detail::mpc_complex_imp<0>
|
||||
template <unsigned D>
|
||||
mpc_complex_backend& operator=(const mpfr_float_backend<D>& val)
|
||||
{
|
||||
mpc_set_prec(this->m_data, mpfr_get_prec(val.data()));
|
||||
if(this->preserve_source_precision())
|
||||
mpc_set_prec(this->m_data, mpfr_get_prec(val.data()));
|
||||
mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
|
||||
return *this;
|
||||
}
|
||||
@@ -1160,10 +1161,13 @@ inline void assign_components(mpc_complex_backend<D1>& result, const mpfr_float_
|
||||
// This is called from class number's constructors, so if we have variable
|
||||
// precision, then copy the precision of the source variables.
|
||||
//
|
||||
if (!D1)
|
||||
BOOST_IF_CONSTEXPR(!D1)
|
||||
{
|
||||
unsigned long prec = (std::max)(mpfr_get_prec(a.data()), mpfr_get_prec(b.data()));
|
||||
mpc_set_prec(result.data(), prec);
|
||||
if ((result.thread_default_variable_precision_options() & variable_precision_options::precision_group) == variable_precision_options::preserve_source_precision)
|
||||
{
|
||||
unsigned long prec = (std::max)(mpfr_get_prec(a.data()), mpfr_get_prec(b.data()));
|
||||
mpc_set_prec(result.data(), prec);
|
||||
}
|
||||
}
|
||||
using default_ops::eval_fpclassify;
|
||||
if (eval_fpclassify(a) == (int)FP_NAN)
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
#include <boost/multiprecision/detail/big_lanczos.hpp>
|
||||
#include <boost/multiprecision/detail/digits.hpp>
|
||||
#include <boost/multiprecision/detail/precision.hpp>
|
||||
#include <boost/multiprecision/detail/atomic.hpp>
|
||||
#include <boost/multiprecision/traits/max_digits10.hpp>
|
||||
#include <boost/multiprecision/mpfr.hpp>
|
||||
@@ -93,6 +94,13 @@ struct mpfi_float_imp
|
||||
if (o.m_data[0].left._mpfr_d)
|
||||
mpfi_set(m_data, o.m_data);
|
||||
}
|
||||
template <unsigned D, mpfr_allocation_type AllocationType>
|
||||
mpfi_float_imp(const mpfr_float_imp<D, AllocationType>& o)
|
||||
{
|
||||
mpfi_init2(m_data, preserve_source_precision() ? mpfr_get_prec(o.data()) : boost::multiprecision::detail::digits10_2_2(get_default_precision()));
|
||||
if (o.data()[0]._mpfr_d)
|
||||
mpfi_set_fr(m_data, o.data());
|
||||
}
|
||||
// rvalue copy
|
||||
mpfi_float_imp(mpfi_float_imp&& o) noexcept
|
||||
{
|
||||
@@ -386,6 +394,10 @@ struct mpfi_float_backend : public detail::mpfi_float_imp<digits10>
|
||||
{
|
||||
mpfi_set(this->m_data, val.data());
|
||||
}
|
||||
template <unsigned D, mpfr_allocation_type AllocationType>
|
||||
mpfi_float_backend(const mpfr_float_backend<D, AllocationType>& val, typename std::enable_if<D <= digits10>::type* = 0)
|
||||
: detail::mpfi_float_imp<digits10>(val) {}
|
||||
|
||||
template <unsigned D>
|
||||
explicit mpfi_float_backend(const mpfi_float_backend<D>& val, typename std::enable_if<!(D <= digits10)>::type* = 0)
|
||||
: detail::mpfi_float_imp<digits10>()
|
||||
@@ -463,6 +475,11 @@ struct mpfi_float_backend<0> : public detail::mpfi_float_imp<0>
|
||||
mpfi_set(this->m_data, val);
|
||||
}
|
||||
mpfi_float_backend(const mpfi_float_backend& o) : detail::mpfi_float_imp<0>(o) {}
|
||||
|
||||
template <unsigned D, mpfr_allocation_type AllocationType>
|
||||
mpfi_float_backend(const mpfr_float_backend<D, AllocationType>& val)
|
||||
: detail::mpfi_float_imp<0>(val) {}
|
||||
|
||||
// rvalue copy
|
||||
mpfi_float_backend(mpfi_float_backend&& o) noexcept : detail::mpfi_float_imp<0>(static_cast<detail::mpfi_float_imp<0>&&>(o))
|
||||
{}
|
||||
@@ -475,6 +492,7 @@ struct mpfi_float_backend<0> : public detail::mpfi_float_imp<0>
|
||||
mpfi_float_backend(const V& a, const V& b, unsigned digits10)
|
||||
: detail::mpfi_float_imp<0>(multiprecision::detail::digits10_2_2(digits10))
|
||||
{
|
||||
boost::multiprecision::detail::scoped_target_precision<mpfi_float_backend<0> > opts;
|
||||
assign_components(*this, a, b);
|
||||
}
|
||||
|
||||
@@ -850,6 +868,19 @@ inline void eval_convert_to(long double* result, const mpfi_float_backend<digits
|
||||
template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
|
||||
inline void assign_components(mpfi_float_backend<D1>& result, const mpfr_float_backend<D2, AllocationType>& a, const mpfr_float_backend<D2, AllocationType>& b)
|
||||
{
|
||||
//
|
||||
// This is called from class number's constructors, so if we have variable
|
||||
// precision, then copy the precision of the source variables.
|
||||
//
|
||||
BOOST_IF_CONSTEXPR(!D1)
|
||||
{
|
||||
if ((result.thread_default_variable_precision_options() & variable_precision_options::precision_group) == variable_precision_options::preserve_source_precision)
|
||||
{
|
||||
unsigned long prec = (std::max)(mpfr_get_prec(a.data()), mpfr_get_prec(b.data()));
|
||||
mpfi_set_prec(result.data(), prec);
|
||||
}
|
||||
}
|
||||
|
||||
using default_ops::eval_fpclassify;
|
||||
if (eval_fpclassify(a) == (int)FP_NAN)
|
||||
{
|
||||
|
||||
@@ -409,6 +409,23 @@ class number
|
||||
typename std::enable_if<std::is_convertible<V, self_type>::value, number<Backend, ExpressionTemplates>&>::type
|
||||
BOOST_MP_CXX14_CONSTEXPR operator+=(const V& v)
|
||||
{
|
||||
detail::scoped_default_precision<number<Backend, ExpressionTemplates> > precision_guard(*this, v);
|
||||
//
|
||||
// If the current precision of *this differs from that of value v, then we
|
||||
// create a temporary (which will have the correct precision thanks to precision_guard)
|
||||
// and then move the result into *this. In C++17 we add a leading "if constexpr"
|
||||
// which causes this code to be eliminated in the common case that this type is
|
||||
// not actually variable precision. Pre C++17 this code should still be mostly
|
||||
// optimised away, but we can't prevent instantiation of the dead code leading
|
||||
// to longer build and possibly link times.
|
||||
//
|
||||
BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(number)
|
||||
if (precision_guard.precision() != boost::multiprecision::detail::current_precision_of(*this))
|
||||
{
|
||||
number t(*this + v);
|
||||
return *this = std::move(t);
|
||||
}
|
||||
|
||||
using default_ops::eval_add;
|
||||
eval_add(m_backend, canonical_value(v));
|
||||
return *this;
|
||||
@@ -457,6 +474,23 @@ class number
|
||||
BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, self_type>::value, number<Backend, ExpressionTemplates>&>::type
|
||||
operator-=(const V& v)
|
||||
{
|
||||
detail::scoped_default_precision<number<Backend, ExpressionTemplates> > precision_guard(*this, v);
|
||||
//
|
||||
// If the current precision of *this differs from that of value v, then we
|
||||
// create a temporary (which will have the correct precision thanks to precision_guard)
|
||||
// and then move the result into *this. In C++17 we add a leading "if constexpr"
|
||||
// which causes this code to be eliminated in the common case that this type is
|
||||
// not actually variable precision. Pre C++17 this code should still be mostly
|
||||
// optimised away, but we can't prevent instantiation of the dead code leading
|
||||
// to longer build and possibly link times.
|
||||
//
|
||||
BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(number)
|
||||
if (precision_guard.precision() != boost::multiprecision::detail::current_precision_of(*this))
|
||||
{
|
||||
number t(*this - v);
|
||||
return *this = std::move(t);
|
||||
}
|
||||
|
||||
using default_ops::eval_subtract;
|
||||
eval_subtract(m_backend, canonical_value(v));
|
||||
return *this;
|
||||
@@ -536,6 +570,23 @@ class number
|
||||
BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, self_type>::value, number<Backend, ExpressionTemplates>&>::type
|
||||
operator*=(const V& v)
|
||||
{
|
||||
detail::scoped_default_precision<number<Backend, ExpressionTemplates> > precision_guard(*this, v);
|
||||
//
|
||||
// If the current precision of *this differs from that of value v, then we
|
||||
// create a temporary (which will have the correct precision thanks to precision_guard)
|
||||
// and then move the result into *this. In C++17 we add a leading "if constexpr"
|
||||
// which causes this code to be eliminated in the common case that this type is
|
||||
// not actually variable precision. Pre C++17 this code should still be mostly
|
||||
// optimised away, but we can't prevent instantiation of the dead code leading
|
||||
// to longer build and possibly link times.
|
||||
//
|
||||
BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(number)
|
||||
if (precision_guard.precision() != boost::multiprecision::detail::current_precision_of(*this))
|
||||
{
|
||||
number t(*this + v);
|
||||
return *this = std::move(t);
|
||||
}
|
||||
|
||||
using default_ops::eval_multiply;
|
||||
eval_multiply(m_backend, canonical_value(v));
|
||||
return *this;
|
||||
@@ -689,6 +740,23 @@ class number
|
||||
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_convertible<V, self_type>::value, number<Backend, ExpressionTemplates>&>::type
|
||||
operator/=(const V& v)
|
||||
{
|
||||
detail::scoped_default_precision<number<Backend, ExpressionTemplates> > precision_guard(*this, v);
|
||||
//
|
||||
// If the current precision of *this differs from that of value v, then we
|
||||
// create a temporary (which will have the correct precision thanks to precision_guard)
|
||||
// and then move the result into *this. In C++17 we add a leading "if constexpr"
|
||||
// which causes this code to be eliminated in the common case that this type is
|
||||
// not actually variable precision. Pre C++17 this code should still be mostly
|
||||
// optimised away, but we can't prevent instantiation of the dead code leading
|
||||
// to longer build and possibly link times.
|
||||
//
|
||||
BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(number)
|
||||
if (precision_guard.precision() != boost::multiprecision::detail::current_precision_of(*this))
|
||||
{
|
||||
number t(*this + v);
|
||||
return *this = std::move(t);
|
||||
}
|
||||
|
||||
using default_ops::eval_divide;
|
||||
eval_divide(m_backend, canonical_value(v));
|
||||
return *this;
|
||||
|
||||
@@ -101,6 +101,78 @@ void test()
|
||||
BOOST_CHECK_EQUAL(a.precision(), 100);
|
||||
a = new_value<T>();
|
||||
BOOST_CHECK_EQUAL(a.precision(), 35);
|
||||
|
||||
if constexpr (!std::is_same_v<T, typename T::value_type>)
|
||||
{
|
||||
//
|
||||
// If we have a component type: ie we are an interval or a complex number, then
|
||||
// operations involving the component type should match those of T:
|
||||
//
|
||||
using component_t = typename T::value_type;
|
||||
component_t::thread_default_precision(100);
|
||||
component_t::thread_default_variable_precision_options(boost::multiprecision::variable_precision_options::preserve_source_precision);
|
||||
|
||||
component_t cp1("0.1"), cp2("0.3"), cp3("0.11"), cp4("0.1231");
|
||||
|
||||
BOOST_CHECK_EQUAL(cp1.precision(), 100);
|
||||
BOOST_CHECK_EQUAL(cp2.precision(), 100);
|
||||
|
||||
component_t::thread_default_precision(35);
|
||||
|
||||
T aa(cp1);
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 100);
|
||||
T cc(cp1, cp2);
|
||||
BOOST_CHECK_EQUAL(cc.precision(), 100);
|
||||
T dd(cp1, cp2, 55);
|
||||
BOOST_CHECK_EQUAL(dd.precision(), 55);
|
||||
aa = new_value<T>();
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 35);
|
||||
if constexpr (std::is_assignable_v<T, component_t>)
|
||||
{
|
||||
aa = cp1;
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 100);
|
||||
aa = new_value<T>();
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 35);
|
||||
aa = std::move(cp1);
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 100);
|
||||
aa = new_value<T>();
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 35);
|
||||
}
|
||||
T bb(std::move(cp2));
|
||||
BOOST_CHECK_EQUAL(bb.precision(), 100);
|
||||
bb = new_value<T>();
|
||||
BOOST_CHECK_EQUAL(bb.precision(), 35);
|
||||
|
||||
if constexpr (boost::multiprecision::is_compatible_arithmetic_type<component_t, T>::value)
|
||||
{
|
||||
aa = bb + cp3;
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 100);
|
||||
aa = new_value<T>();
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 35);
|
||||
aa = cp3 * bb;
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 100);
|
||||
aa = new_value<T>();
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 35);
|
||||
aa += cp3;
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 100);
|
||||
aa = new_value<T>();
|
||||
aa -= cp3;
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 100);
|
||||
aa = new_value<T>();
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 35);
|
||||
aa *= cp4;
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 100);
|
||||
aa = new_value<T>();
|
||||
aa /= cp4;
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 100);
|
||||
aa = new_value<T>();
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 35);
|
||||
aa -= bb * cp3;
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 100);
|
||||
aa = new_value<T>();
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 35);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
|
||||
@@ -77,6 +77,52 @@ void test()
|
||||
BOOST_CHECK_EQUAL(a.precision(), 35);
|
||||
a -= b * hp3;
|
||||
BOOST_CHECK_EQUAL(a.precision(), 35);
|
||||
|
||||
if constexpr (!std::is_same_v<T, typename T::value_type>)
|
||||
{
|
||||
//
|
||||
// If we have a component type: ie we are an interval or a complex number, then
|
||||
// operations involving the component type should match those of T:
|
||||
//
|
||||
using component_t = typename T::value_type;
|
||||
component_t::thread_default_precision(100);
|
||||
component_t::thread_default_variable_precision_options(boost::multiprecision::variable_precision_options::preserve_source_precision);
|
||||
|
||||
component_t cp1("0.1"), cp2("0.3"), cp3("0.11"), cp4("0.1231");
|
||||
|
||||
BOOST_CHECK_EQUAL(cp1.precision(), 100);
|
||||
BOOST_CHECK_EQUAL(cp2.precision(), 100);
|
||||
|
||||
T::thread_default_precision(35);
|
||||
|
||||
T aa(cp1);
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 35);
|
||||
T cc(cp1, cp2);
|
||||
BOOST_CHECK_EQUAL(cc.precision(), 35);
|
||||
T dd(cp1, cp2, 20);
|
||||
BOOST_CHECK_EQUAL(dd.precision(), 20);
|
||||
aa = cp1;
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 35);
|
||||
aa = std::move(cp1);
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 35);
|
||||
T bb(std::move(cp2));
|
||||
BOOST_CHECK_EQUAL(bb.precision(), 35);
|
||||
|
||||
aa = bb + cp3;
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 35);
|
||||
aa = cp3 * bb;
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 35);
|
||||
aa += cp3;
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 35);
|
||||
aa -= cp3;
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 35);
|
||||
aa *= cp4;
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 35);
|
||||
aa /= cp4;
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 35);
|
||||
aa -= bb * cp3;
|
||||
BOOST_CHECK_EQUAL(aa.precision(), 35);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
|
||||
Reference in New Issue
Block a user