Opened 11 years ago

Closed 10 years ago

Last modified 10 years ago

#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)

max_digits10.diff (959 bytes ) - added by Jürgen Hunold 10 years ago.
Check for BOOST_NO_NUMERIC_LIMITS_LOWEST

Download all attachments as: .zip

Change History (8)

comment:1 by Paul A. Bristow, 10 years ago

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

[1e+2776234983093287513 != 1e+2776234983093287513]

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.

comment:2 by Paul A. Bristow, 10 years ago

Resolution: fixed
Status: newclosed

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 Paul A. Bristow, 10 years ago

Comment out this until can find a way to check if max_digits10 is supported.

comment:4 by Jeff Trull <edaskel@…>, 10 years ago

Also see bug 6986; I echo pbristow's third comment.

comment:5 by Jürgen Hunold, 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.

by Jürgen Hunold, 10 years ago

Attachment: max_digits10.diff added

Check for BOOST_NO_NUMERIC_LIMITS_LOWEST

comment:6 by Paul A. Bristow, 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 Paul A. Bristow, 10 years ago

Milestone: Boost 1.48.0Boost 1.51.0
Note: See TracTickets for help on using tickets.