#5758 closed Support Requests (fixed)
Boost.Test Floating-point comparison diagnostic output does not support radix 10
Reported by: | Paul A. Bristow | Owned by: | Gennadiy Rozental |
---|---|---|---|
Milestone: | Boost 1.51.0 | Component: | test |
Version: | Boost Development Trunk | Severity: | Problem |
Keywords: | floating point radix 10 decimal precision | Cc: |
Description
Boost.Test Floating-point comparison diagnostic output does not support radix 10.
This emerged as a problem writing tests for Christopher Kormanyos proposed e_float extended precision float library which uses radix 10.
Tests that fail do not provide sufficient decimal digits to reveal why the test fails.
Numeric_limits is properly specialized for e_float, so max_digits10 is valid (and this is also true for a recent fixed decimal library.
So I suggest that in test_tools.hpp function set_precision
After dealing with the radix = 2 case,
(and noting that although we would like to rely on max_digits10, older compilers/libraries do not provide it, and the recent MS VC10 wrongly implements float max_digits10 as 8 instead of 9, it is safer to continue to use the original Kahan formula)>
Ideally should use max_digits10 if available, and correct! But this always works.
if( std::numeric_limits<T>::is_specialized && std::numeric_limits<T>::radix
Add new code to deal with the radix=10 case (but in this case we can rely on max_digits10)
If radix = 10, is recent code so assume max_digits10 should be correct. For example, e_float and a fixed decimal package(s) both comply.
if( std::numeric_limits<T>::is_specialized && std::numeric_limits<T>::radix == 10 )
ostr.precision( std::numeric_limits<T>::max_digits10 );
(Might also be worth a comment that for other cases, precision will remain at the default value, whatever that is).
This has been tested and works as expected for e_float.
Attachments (1)
Change History (8)
comment:1 by , 10 years ago
comment:2 by , 10 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Patch committed Completed: At revision: 78908
if( std::numeric_limits<T>::is_specialized && std::numeric_limits<T>::radix == 10 )
ostr.precision( 2 + std::numeric_limits<T>::max_digits10);
This assumes that any new radix 10 library will implement max_digits10 as it should to be standard compliant.
comment:3 by , 10 years ago
Comment out this until can find a way to check if max_digits10 is supported.
comment:5 by , 10 years ago
I tested John suggestion on the ML thread and successfully used BOOST_NO_NUMERIC_LIMITS_LOWEST. Patch attached. I will also ask on the ML.
comment:6 by , 10 years ago
Using John Maddock and Christopher Kormanyos mutliprecision currently under review
BOOST_AUTO_TEST_CASE(cpp_loopback_test_message) { Loopback.
using namespace boost::multiprecision;
cpp_dec_float_100 a = "1."; cpp_dec_float_100 b = "1."; b += 1e-100;
BOOST_CHECK_EQUAL(a, b);
} BOOST_AUTO_TEST_CASE(cpp_loopback_test_message)
Gives this misleading message
error : in "cpp_loopback_test_message": check a == b failed [1 != 1]
else if ( std::numeric_limits<T>::is_specialized && std::numeric_limits<T>::radix == 10 )
adding this to cater for radix 10
{
#ifdef BOOST_NO_NUMERIC_LIMITS_LOWEST No support for std::numeric_limits<double>::max_digits10; so guess that a couple of guard digits more than digits10 will display any difference.
ostr.precision( 2 + std::numeric_limits<T>::digits10 );
#else
std::numeric_limits<double>::max_digits10; IS supported. Any noisy or guard digits needed to display any difference are included in max_digits10.
ostr.precision( std::numeric_limits<T>::max_digits10 );
#endif
} else if T is not specialized, then will just get the default precision of 6 digits.
gives this more helpful mesage
in "cpp_loopback_test_message": check a == b failed [1 != 1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000001999]
BOOST_NO_NUMERIC_LIMITS_LOWEST is a proxy for support of max_digits10.
And seems to work in tests using Boost.Math.
At present only MSVC 10 and some gcc test platforms support max_digits10.
Sandia clang darwin trunk c++11 seems to fail with and without check for BOOST_NO_NUMERIC_LIMITS_LOWEST.
Please tell me immediately of any problem this revised version causes.
comment:7 by , 10 years ago
Milestone: | Boost 1.48.0 → Boost 1.51.0 |
---|
This is also essential for the proposed Boost.Multiprecision (and probably proposed fixed-point).
At 1.50
I:/boost-sandbox/big_number/libs/multiprecision/test/math/test_cpp_float_loopback.cpp(66): error : in "cpp_loopback_test_max": check l == b failed
which is most misleading (and nonsensical)
Patched as proposed to use max_digits10 above gives the correct (and sensible) display
I:/boost-sandbox/big_number/libs/multiprecision/test/math/test_cpp_float_loopback.cpp(66): error : in "cpp_loopback_test_max": check l == b failed
[1e+2776234983093287513 != 9.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999e+2776234983093287512]
It would be very useful if this was corrected for 1.51 when Boost.Multiprecision will probably be included.