Opened 5 years ago

Closed 3 years ago

#8272 closed Bugs (fixed)

BOOST_REQUIRE_CLOSE fails to compile with boost::multiprecision::cpp_dec_float_100

Reported by: Ken Smith <kgsmith@…> Owned by: Gennadiy Rozental
Milestone: Boost 1.59.0 Component: test
Version: Boost 1.53.0 Severity: Problem
Keywords: test multiprecision check_is_close is_close_to Cc: pbristow@…

Description

Environment:

  • Linux 3.7.9-2-ARCH
  • G++ 4.7.2
  • Issue reproduces with Boost SVN trunk

This code:

#define BOOST_TEST_MAIN
#include <boost/test/included/unit_test.hpp>
#include <boost/test/floating_point_comparison.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>

BOOST_AUTO_TEST_CASE(multiprecision_closeness)
{
   using num_t = boost::multiprecision::cpp_dec_float_100;

   num_t a("1.0000000000000000000000000000001");
   num_t b(1);
   num_t thresh(1e-15);

   BOOST_REQUIRE_CLOSE(a, b, thresh);
}

Generates the following compilation error:

g++ -std=gnu++11 -g -Iboost-trunk -o prog repro.cpp
In file included from boost-trunk/boost/test/tools/old/impl.hpp:21:0,
                 from boost-trunk/boost/test/test_tools.hpp:32,
                 from boost-trunk/boost/test/impl/exception_safety.ipp:35,
                 from boost-trunk/boost/test/included/unit_test.hpp:22,
                 from repro.cpp:2:
boost-trunk/boost/test/tools/floating_point_comparison.hpp: In instantiation of ‘FPT boost::math::fpc::fpc_detail::fpt_abs(FPT) [with FPT = boost::multiprecision::detail::expression<boost::multiprecision::detail::subtract_immediates, boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<100u> >, boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<100u> >, void, void>]’:
boost-trunk/boost/test/tools/floating_point_comparison.hpp:207:67:   required from ‘bool boost::math::fpc::close_at_tolerance<FPT>::operator()(FPT, FPT) const [with FPT = boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<100u> >]’
boost-trunk/boost/test/tools/old/impl.hpp:292:50:   required from ‘boost::test_tools::assertion_result boost::test_tools::check_is_close_t::operator()(FPT1, FPT2, ToleranceType) const [with FPT1 = boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<100u> >; FPT2 = boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<100u> >; ToleranceType = boost::math::fpc::percent_tolerance_t<boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<100u> > >]’
boost-trunk/boost/test/tools/old/impl.hpp:91:1:   required from ‘bool boost::test_tools::tt_detail::check_frwd(Pred, const boost::unit_test::lazy_ostream&, boost::unit_test::const_string, std::size_t, boost::test_tools::tt_detail::tool_level, boost::test_tools::tt_detail::check_type, const Arg0&, const char*, const Arg1&, const char*, const Arg2&, const char*) [with Pred = boost::test_tools::check_is_close_t; Arg0 = boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<100u> >; Arg1 = boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<100u> >; Arg2 = boost::math::fpc::percent_tolerance_t<boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<100u> > >; boost::unit_test::const_string = boost::unit_test::basic_cstring<const char>; std::size_t = long unsigned int]’
repro.cpp:14:1:   required from here
boost-trunk/boost/test/tools/floating_point_comparison.hpp:59:47: error: no matching function for call to ‘boost::multiprecision::detail::expression<boost::multiprecision::detail::subtract_immediates, boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<100u> >, boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<100u> >, void, void>::expression(int)’
boost-trunk/boost/test/tools/floating_point_comparison.hpp:59:47: note: candidates are:
In file included from boost-trunk/boost/multiprecision/detail/default_ops.hpp:10:0,
                 from boost-trunk/boost/multiprecision/detail/generic_interconvert.hpp:9,
                 from boost-trunk/boost/multiprecision/number.hpp:22,
                 from boost-trunk/boost/multiprecision/cpp_dec_float.hpp:28,
                 from repro.cpp:4:
boost-trunk/boost/multiprecision/detail/number_base.hpp:379:4: note: boost::multiprecision::detail::expression<tag, Arg1, Arg2, void, void>::expression(const Arg1&, const Arg2&) [with tag = boost::multiprecision::detail::subtract_immediates; Arg1 = boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<100u> >; Arg2 = boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<100u> >]
boost-trunk/boost/multiprecision/detail/number_base.hpp:379:4: note:   candidate expects 2 arguments, 1 provided
boost-trunk/boost/multiprecision/detail/number_base.hpp:369:8: note: constexpr boost::multiprecision::detail::expression<boost::multiprecision::detail::subtract_immediates, boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<100u> >, boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<100u> >, void, void>::expression(const boost::multiprecision::detail::expression<boost::multiprecision::detail::subtract_immediates, boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<100u> >, boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<100u> >, void, void>&)
boost-trunk/boost/multiprecision/detail/number_base.hpp:369:8: note:   no known conversion for argument 1 from ‘int’ to ‘const boost::multiprecision::detail::expression<boost::multiprecision::detail::subtract_immediates, boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<100u> >, boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<100u> >, void, void>&’
make: *** [prog] Error 1

At line 59 of floating_point_comparison.hpp, FPT appears to be an expression template and doesn't suffer the static cast.

Attachments (2)

test_expression_template_fpt.cpp (1.0 KB) - added by John Maddock 5 years ago.
Test cases.
test_multiprecision.patch (4.8 KB) - added by John Maddock 5 years ago.
Patches to make Boost.Test work with expression template types.

Download all attachments as: .zip

Change History (5)

comment:1 Changed 5 years ago by John Maddock

Cc: pbristow@… added
Owner: changed from John Maddock to Gennadiy Rozental

Boost.Test knows nothing of expression template types internally and so can't cope with these. The fixes are reasonably easy, but it's up to Boost.Test's maintainer to decide whether to support this use case or not. One fix on your side is to cast arguments to Boost.Test macros to a multiprecision type that has expression template support turned off.

Gennadiy, I'm attaching patches and a test case (which IMO belongs in the Boost.Test test suite if you choose to approve the patches), can you take a look?

Also adding Paul Bristow in the loop, as I know he hit this one too.

Changed 5 years ago by John Maddock

Test cases.

Changed 5 years ago by John Maddock

Attachment: test_multiprecision.patch added

Patches to make Boost.Test work with expression template types.

comment:2 Changed 5 years ago by John Maddock

Component: multiprecisiontest

Updated patch (adds missing #include plus test case and Jamfile edits).

Tested OK with msvc-9 and 10. GCC-4.7.2, and Intel-13.

comment:3 Changed 3 years ago by Raffi Enficiaud

Milestone: To Be DeterminedBoost 1.59.0
Resolution: fixed
Status: newclosed

Duplicates #11054 - added the test case fp-multiprecision-comparison:

https://github.com/boostorg/test/blob/master/test/writing-test-ts/fp-multiprecision-comparison-test.cpp

testing the previous and BOOST_TEST API conformance with multiprecision.

Note: See TracTickets for help on using tickets.