[Test] BOOST_CHECK_CLOSE Feature request

I have a couple of feature requests for Boost.Test: 1) Can BOOST_CHECK_CLOSE please print the actual difference between the values (as a percent to match the tolerance) as well as the values themselves? The reason this is important, is that it's not always easy to get this value from the input values - because the precision of the machine on which the test is run far outstrips that of the author's machine, so his calculator isn't any use :-( 2) Can we please have a BOOST_CHECK_EPSILON, that uses a whole number of epsilon as the tolerance? IMO BOOST_CHECK_CLOSE should have been written this way to begin with, but it's too late now. Again it should print out the actual relative error as a multiple of epsilon as well as the input values. Actually while we're at it the absolute error may be useful to have in some situations as well :-) BTW, in case it helps: I've switched to using std::pow(two, 1-std::numeric_limits<T>::digits) to calculate machine epsilon, because of the strange behaviour on Darwin with long doubles if you use numeric_limits<>::epsilon() (see http://lists.boost.org/Archives/boost/2005/09/93390.php). Thanks! John.

"John Maddock" <john@johnmaddock.co.uk> wrote in message news:005301c5e616$7a3cef90$5c410352@fuji...
I have a couple of feature requests for Boost.Test:
1) Can BOOST_CHECK_CLOSE please print the actual difference between the values (as a percent to match the tolerance) as well as the values themselves? The reason this is important, is that it's not always easy to get this value from the input values - because the precision of the machine on which the test is run far outstrips that of the author's machine, so his calculator isn't any use :-(
This is doable. The message would sould like this: difference between var1 {<value>} and var2 {<value>} is x% and exceeds e%
2) Can we please have a BOOST_CHECK_EPSILON, that uses a whole number of epsilon as the tolerance? IMO BOOST_CHECK_CLOSE should have been written this way to begin with, but it's too late now
Actually it was this way originally. It was causing constant confusion with absolute comparison. I thought persents will bring better message. Unfortunately many users since then indicated that original version (for those who knew how to use it) was better. If there is a general consensus I am willing to rollback. Or we could introduce a new tool.
Again it should print out the actual relative error as a multiple of epsilon as well as the input values. Actually while we're at it the absolute error may be useful to have in some situations as well :-)
This one already exists: BOOST_CHECK_SMALL( v, epsilon )
BTW, in case it helps: I've switched to using std::pow(two, 1-std::numeric_limits<T>::digits) to calculate machine epsilon, because of the strange behaviour on Darwin with long doubles if you use numeric_limits<>::epsilon() (see http://lists.boost.org/Archives/boost/2005/09/93390.php).
I will consider this.
Thanks!
John.
Regards, Gennadiy

On Thursday 10 November 2005 18:33, Gennadiy Rozental wrote:
"John Maddock" <john@johnmaddock.co.uk> wrote in message news:005301c5e616$7a3cef90$5c410352@fuji...
I have a couple of feature requests for Boost.Test:
1) Can BOOST_CHECK_CLOSE please print the actual difference between the values (as a percent to match the tolerance) as well as the values themselves? The reason this is important, is that it's not always easy to get this value from the input values - because the precision of the machine on which the test is run far outstrips that of the author's machine, so his calculator isn't any use :-(
This is doable. The message would sould like this:
difference between var1 {<value>} and var2 {<value>} is x% and exceeds e%
Why are we using percentage and not and not the epsilon value? Percentage just causes you to have to move the point 2 digits in your head.
2) Can we please have a that uses a whole number of epsilon as the tolerance? IMO BOOST_CHECK_CLOSE should have been written this way to begin with, but it's too late now
Actually it was this way originally. It was causing constant confusion with absolute comparison. I thought persents will bring better message. Unfortunately many users since then indicated that original version (for those who knew how to use it) was better. If there is a general consensus I am willing to rollback. Or we could introduce a new tool.
I see, I also read the docs on this. Maybe using percent give unitroduced users a better hint that it is the difference between the two values as a percentage of their distance to zero that is tested -- not a maximum value for the absolute difference between the two. I guess this is because it is hard to understand how to express an absolute value as a percentage. Hence, you kind of force them to study what to put in as parameter, make them read the documentation. If you just throw "the value of epsilon" at them, they may be more likely to be confused. I support having BOOST_CHECK_EPSILON as suggested as an alternative, its name suggest a clear meaning to those that have studied the concepts described in http://www.boost.org/libs/test/doc/components/test_tools/floating_point_comp... maybe a better name would be BOOST_CHECK_CLOSE_EPSILON as it suggest the strong relationship to BOOST_CHECK_CLOSE. After all their functionallity is the same, just different expectations on one parameter.
Again it should print out the actual relative error as a multiple of epsilon as well as the input values.
agree I also read the docs, and spotted some problems: copy/paste error in top of libs/test/doc/components/test_tools/reference/BOOST_CHECK_SMALL.html I suspect: BOOST_WARN_SMALL( val, tolerance ) BOOST_CHECK_CLOSE( val, tolerance ) BOOST_REQUIRE_CLOSE( val, tolerance ) should have been: BOOST_WARN_SMALL( val, tolerance ) BOOST_CHECK_SMALL( val, tolerance ) BOOST_REQUIRE_SMALL( val, tolerance ) and file:///dsk1/src/boost_1_33_0/libs/test/doc/components/test_tools/floating_point_comparison.html unreasonable to use an operator=(...) f ^^^^^ should be operator equal not asignment below that in same file I read: (firefox) u - v | <= e * |u| and | u - v | <= e * |v| ^^^ missing | caused by: <P style="text-indent: -20"> |<I> u </I>-<I> v </I>| <= <I>e * |u|</I> and ^^^^^^^^^^^^^^ in the html souce. regards, Bjørn Roald

This is doable. The message would sould like this:
difference between var1 {<value>} and var2 {<value>} is x% and exceeds e%
Good. This one is quite pressing for me, as there are some failing tests I can't diagnose otherwise :-/
2) Can we please have a BOOST_CHECK_EPSILON, that uses a whole number of epsilon as the tolerance? IMO BOOST_CHECK_CLOSE should have been written this way to begin with, but it's too late now
Actually it was this way originally. It was causing constant confusion with absolute comparison. I thought persents will bring better message. Unfortunately many users since then indicated that original version (for those who knew how to use it) was better. If there is a general consensus I am willing to rollback. Or we could introduce a new tool.
Has to be a new tool, too much would break otherwise, I like the name BOOST_CHECK_CLOSE_EPSILON suggested elsewhere.
Again it should print out the actual relative error as a multiple of epsilon as well as the input values. Actually while we're at it the absolute error may be useful to have in some situations as well :-)
This one already exists: BOOST_CHECK_SMALL( v, epsilon )
Sorry that's not what I meant, I meant when BOOST_CHECK_CLOSE or BOOST_CHECK_CLOSE_EPSILON fail then they should print out: The two input values. The max relative error permitted. The actual relative error found. The actual absolute error found. More information is a good thing in this case :-) Regards, John.

"John Maddock" <john@johnmaddock.co.uk> wrote in message news:003c01c5e791$4b0cee60$19d96b51@fuji...
This is doable. The message would sould like this:
difference between var1 {<value>} and var2 {<value>} is x% and exceeds e%
Good. This one is quite pressing for me, as there are some failing tests I can't diagnose otherwise :-/
I am working on Boost.Test update these days. I hope it to be soon.
Has to be a new tool, too much would break otherwise, I like the name BOOST_CHECK_CLOSE_EPSILON suggested elsewhere.
Ok. So be it. Actually An ideal solution would be somethind like: BOOST_CHECK_CLOSE( a, b , 0.5% ) - test in percents BOOST_CHECK_CLOSE( a, b , 0.05) - test in epsilon But I couldn't figure out how implement it
This one already exists: BOOST_CHECK_SMALL( v, epsilon )
Sorry that's not what I meant, I meant when BOOST_CHECK_CLOSE or BOOST_CHECK_CLOSE_EPSILON fail then they should print out:
The two input values. The max relative error permitted. The actual relative error found. The actual absolute error found.
More information is a good thing in this case :-)
Absolute difference would clutter output. Especially since it could be completely unrelated. I am not sure we want this always. Gennadiy

Gennadiy Rozental wrote:
Ok. So be it. Actually An ideal solution would be somethind like:
BOOST_CHECK_CLOSE( a, b , 0.5% ) - test in percents BOOST_CHECK_CLOSE( a, b , 0.05) - test in epsilon
But I couldn't figure out how implement it
Maybe this idea helps: #include <iostream> using namespace std; struct Null { Null operator+() const { return Null(); } } null; template< typename T > T operator+( const T& v, const Null& ) { return v; } template< typename T > T operator%( const T& v, const Null& ) { return v / 100; } #define TEST( X ) (X+null) int main() { cout << TEST( 0.5% ) << endl << TEST( 0.05 ) << endl; } Regards, Daniel

On Sunday 13 November 2005 15:43, Gennadiy Rozental wrote:
Ok. So be it. Actually An ideal solution would be somethind like:
BOOST_CHECK_CLOSE( a, b , 0.5% ) - test in percents BOOST_CHECK_CLOSE( a, b , 0.05) - test in epsilon
But I couldn't figure out how implement it
I guess one approach would be to make percent and epsilon small concrete types: BOOST_CHECK_CLOSE( a, b , percent(0.5) ) BOOST_CHECK_CLOSE( a, b , epsilon(0.05)) can then both map to functions of different signatures from current implementation which I guess take a double. In principle you could use boost::rational BOOST_CHECK_CLOSE( a, b , rational(3,5000)) but then the tester uses what is tested, not good :-\ Bjørn

I strongly support John on this request. Having very similar needs with using Boost test on math functions. I've also suspected some strange behaviour caused by the * or / 100.0 which introduces another source of slight change. Paul -- Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB Phone and SMS text +44 1539 561830, Mobile and SMS text +44 7714 330204 mailto: pbristow@hetp.u-net.com www.hetp.u-net.com | -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of John Maddock | Sent: 10 November 2005 16:47 | To: Boost mailing list | Subject: [boost] [Test] BOOST_CHECK_CLOSE Feature request | | I have a couple of feature requests for Boost.Test: | | 1) Can BOOST_CHECK_CLOSE please print the actual difference | between the | values (as a percent to match the tolerance) as well as the values | themselves? The reason this is important, is that it's not | always easy to | get this value from the input values - because the precision | of the machine | on which the test is run far outstrips that of the author's | machine, so his | calculator isn't any use :-( | | 2) Can we please have a BOOST_CHECK_EPSILON, that uses a | whole number of | epsilon as the tolerance? IMO BOOST_CHECK_CLOSE should have | been written | this way to begin with, but it's too late now. Again it | should print out | the actual relative error as a multiple of epsilon as well as | the input | values. Actually while we're at it the absolute error may be | useful to have | in some situations as well :-) | | BTW, in case it helps: I've switched to using std::pow(two, | 1-std::numeric_limits<T>::digits) to calculate machine | epsilon, because of | the strange behaviour on Darwin with long doubles if you use | numeric_limits<>::epsilon() (see | http://lists.boost.org/Archives/boost/2005/09/93390.php). |

Related to this, there is a very interesting article on comparing IEEE floats at http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm This makes use of the property that IEEE floating point formats are lexicographically ordered when reinterpreted as an appropriate length signed integer. It appears you can use this to define a closeness measure based on how many units in the last place the two numbers differ by (equivalently, if you enumerated all possible floats and counted how far away one number is from the other in the enumeration). I only just came across it now so I havn't tried playing with it yet, but it looks like it would make a useful closeness measure. Cheers, Ian McCulloch

Related to this, there is a very interesting article on comparing IEEE floats at http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
This makes use of the property that IEEE floating point formats are lexicographically ordered when reinterpreted as an appropriate length signed integer. It appears you can use this to define a closeness measure based on how many units in the last place the two numbers differ by (equivalently, if you enumerated all possible floats and counted how far away one number is from the other in the enumeration). I only just came across it now so I havn't tried playing with it yet, but it looks like it would make a useful closeness measure.
I must admit I've been looking for a way to measure errors as ULP. However, I have my doubts about this: are integer types and floating point types always of the same endianness? I suspect not, but can't be 100% sure. There are also problems with long doubles to consider: padding bits on some implementations, and strange "a long double is actually a pair of doubles" on Darwin. John.

John Maddock wrote:
Related to this, there is a very interesting article on comparing IEEE floats at http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
This makes use of the property that IEEE floating point formats are lexicographically ordered when reinterpreted as an appropriate length signed integer. It appears you can use this to define a closeness measure based on how many units in the last place the two numbers differ by (equivalently, if you enumerated all possible floats and counted how far away one number is from the other in the enumeration). I only just came across it now so I havn't tried playing with it yet, but it looks like it would make a useful closeness measure.
I must admit I've been looking for a way to measure errors as ULP. However, I have my doubts about this: are integer types and floating point types always of the same endianness? I suspect not, but can't be 100% sure. There are also problems with long doubles to consider: padding bits on some implementations, and strange "a long double is actually a pair of doubles" on Darwin.
It is frustrating, that the article shows that it is quite easy to do a ULP-based comparison given the right hardware (even doing some bit-banging on eg, Darwin would be not so hard), but a portable version to use as a fallback seems really hard. Maybe it is possible using frexp(), ldexp() etc. The problem is if you don't assume IEEE arithmetic, then there isn't much you can guarantee about floating point behaviour. Not to mention handling FLT_RADIX != 2 ... Scalbn() might be useful there, but that is C99 only... There is also the problem of platforms that are not quite IEEE. For example, IIRC on Alpha by default doesn't generate subnormals. Cheers, Ian

| -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of Ian McCulloch | Sent: 13 November 2005 22:11 | To: boost@lists.boost.org | Subject: Re: [boost] [Test] BOOST_CHECK_CLOSE Feature request | | John Maddock wrote: | | >> Related to this, there is a very interesting article on | comparing IEEE | >> floats at | >> | http://www.cygnus-software.com/papers/comparingfloats/comparin | gfloats.htm | >> | >> This makes use of the property that IEEE floating point formats are | >> lexicographically ordered when reinterpreted as an | appropriate length | >> signed integer. It appears you can use this to define a closeness | >> measure based on how many units in the last place the two numbers | >> differ by (equivalently, if you enumerated all possible floats and | >> counted how far | >> away one number is from the other in the enumeration). I only just | >> came across it now so I havn't tried playing with it yet, but it | >> looks like it would make a useful closeness measure. | > | > I must admit I've been looking for a way to measure errors as ULP. | > However, I have my doubts about this: are integer types and | floating point | > types | > always of the same endianness? I suspect not, but can't be | 100% sure. | > There are also problems with long doubles to consider: | padding bits on | > some implementations, and strange "a long double is | actually a pair of | > doubles" on Darwin. | | It is frustrating, that the article shows that it is quite | easy to do a | ULP-based comparison given the right hardware (even doing | some bit-banging | on eg, Darwin would be not so hard), but a portable version | to use as a | fallback seems really hard. Maybe it is possible using | frexp(), ldexp() | etc. The problem is if you don't assume IEEE arithmetic, | then there isn't | much you can guarantee about floating point behaviour. Not to mention | handling FLT_RADIX != 2 ... Scalbn() might be useful there, | but that is | C99 only... But TR1 pulls in C99, so we should be able to start relying on it? | There is also the problem of platforms that are not quite IEEE. For | example, IIRC on Alpha by default doesn't generate subnormals. This is correct, but I am not sure that this matters in making the comparison? Expectations of total portability seem misguided in any case IMO. So can't we simply test for IEEE fp layout with numeric_limits<>::is_iec599() and give up if not? As a specific example, I have recently been using NTL quad_float type (simillar to Darwin long double) to check that the Math functions can use a UDT. This worked fine with Boost Test and I think just adding a version for this and other UDTs as the need arises is all we can hope for. Paul -- Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB Phone and SMS text +44 1539 561830, Mobile and SMS text +44 7714 330204 mailto: pbristow@hetp.u-net.com www.hetp.u-net.com

| -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of John Maddock | Sent: 12 November 2005 17:16 | To: boost@lists.boost.org | Subject: Re: [boost] [Test] BOOST_CHECK_CLOSE Feature request | | > comparing IEEE floats at | http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm | > | > This makes use of the property that IEEE floating point formats are | > lexicographically ordered when reinterpreted as an appropriate length | > signed integer. It appears you can use this to define a closeness | > measure based on how many units in the last place the two numbers | > differ by (equivalently, if you enumerated all possible floats and | > counted how far | > away one number is from the other in the enumeration). I only just | > came across it now so I havn't tried playing with it yet, but it | > looks like it would make a useful closeness measure. I HAVE been playing with it, briefly, and seems to work as expected for MS 8.0 using int for float (or should that be __int32?) using __int64 type for double (and of course long double since it is the same). double a = 1.2; double b = 1.199999999999999; __int64 aInt64 = *(__int64*)&a; // float as 64-bit integer. __int64 bInt64 = *(__int64*)&b; cout << "a = " << a << " " << hex << aInt64 << endl; cout << "b = " << b << " " << hex << bInt64 << endl; __int64 d = aInt64 - bInt64; cout << "diff = " << hex << d << endl; a = 1.2 3ff3333333333333 b = 1.2 3ff333333333332f diff = 4 bool AlmostEqual2sComplement(double A, double B, int maxUlps); cout << boolalpha << AlmostEqual2sComplement(a, b, 2) << endl; outputs false, as expected because difference is 4. But of course, this is the simple case of 64-bit double. No doubt other exotic types can also be compared similarly with some bit twiddling, assuming we can select the right int to match the floating-point type. If int is 64-bit and float is only 32 should still work? But for now perhaps we can test and if not implemented then just give up: // Check is IEEE 754 - but really want a macro. if (!numeric_limits<double>::is_iec559) { // Code below is unsuitable. cout << "is NOT IEC559!" << endl; return -1; } and of course, this doesn't work C1017: invalid integer constant expression #if (!numeric_limits<double>::is_iec559) # pragma error ("NOT IEC559!") #endif #if ((DBL_MANT_DIG == 53) && (DBL_RADIX == 2) && (DBL_MAX_EXP == 1024)) # pragma message ("Is very probably IEC559.") // Want to give up here with pragma error, or something? #endif But I don't know if any of this takes account of (wrong-)endianness. For example, VAX layout is different? Boost test doesn't seem to rely on floating-point layout? Any experts on this, either on an IS_IEEE macro, or endianness? Paul -- Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB Phone and SMS text +44 1539 561830, Mobile and SMS text +44 7714 330204 mailto: pbristow@hetp.u-net.com www.hetp.u-net.com
participants (6)
-
Bjørn Roald
-
Daniel Frey
-
Gennadiy Rozental
-
Ian McCulloch
-
John Maddock
-
Paul A Bristow