BOOST_CHECK_CLOSE with integral types
Hi all, Is BOOST_CHECK_CLOSE supposed to work with integral types? I find that if I try: long var1 = 1001; BOOST_CHECK_CLOSE(var1, 2000L, 10L); under both MSVC 2005 and GCC 3.4, it'll pass, which is wrong as far as I can see - whereas: double var2 = 1001.0; BOOST_CHECK_CLOSE(var2, 2000.0, 10.0); fails as it should. Why is this? int has the same problem. Cheers, Will -- Will Bryant http://carcino.gen.nz/ will@core-dev.co.nz +64 21 655 443
"Will Bryant"
Hi all,
Is BOOST_CHECK_CLOSE supposed to work with integral types? I find that if I try:
long var1 = 1001; BOOST_CHECK_CLOSE(var1, 2000L, 10L);
under both MSVC 2005 and GCC 3.4, it'll pass, which is wrong as far as I can see - whereas:
double var2 = 1001.0; BOOST_CHECK_CLOSE(var2, 2000.0, 10.0);
fails as it should.
Why is this? int has the same problem.
BOOST_CHECK_CLOSE algorithm involves division (it compared relative distance with tolerance). |a-b|/|a| will always produce 0 for integral types. Which is less then any tolerance you could specify. Gennadiy
Gennadiy Rozental wrote:
BOOST_CHECK_CLOSE algorithm involves division (it compared relative distance with tolerance). |a-b|/|a| will always produce 0 for integral types. Which is less then any tolerance you could specify.
But we're comparing it to a 0-100 percentage number, so why can't we just multiply before the division? -- Will Bryant http://carcino.gen.nz/ will@core-dev.co.nz +64 21 655 443
BOOST_CHECK_CLOSE algorithm involves division (it compared relative distance with tolerance). |a-b|/|a| will always produce 0 for integral types. Which is less then any tolerance you could specify.
But we're comparing it to a 0-100 percentage number, so why can't we just multiply before the division?
I chose to divide percent tolerance by 100 (multiplication would lead to overflow issues). BOOST_CHECK_CLOSE doesn't really fit for integral type closeness check. You could use BOOST_CHECK_SMALL instead. Gennadiy
Gennadiy Rozental wrote:
I chose to divide percent tolerance by 100 (multiplication would lead to overflow issues). BOOST_CHECK_CLOSE doesn't really fit for integral type closeness check. You could use BOOST_CHECK_SMALL instead.
Would it not be useful to provide a specialisation of the comparison template for integral types? The current semantics aren't useful IMHO - they just give undocumented false test passes - so even a naive implementation which risked overflow would be an improvement. But we can actually prevent overflow - just check if |a-b| is >= the maximum value for the integer type / 100, if not use 100*|a-b|/a, if so use something like |a-b|/(a/100). Will -- Will Bryant http://carcino.gen.nz/ will@core-dev.co.nz +64 21 655 443
I chose to divide percent tolerance by 100 (multiplication would lead to overflow issues). BOOST_CHECK_CLOSE doesn't really fit for integral type closeness check. You could use BOOST_CHECK_SMALL instead.
Would it not be useful to provide a specialisation of the comparison template for integral types? The current semantics aren't useful IMHO - they just give undocumented false test passes - so even a naive implementation which risked overflow would be an improvement.
But we can actually prevent overflow - just check if |a-b| is >= the maximum value for the integer type / 100, if not use 100*|a-b|/a, if so use something like |a-b|/(a/100).
I will consider this next release. Gennadiy
participants (2)
-
Gennadiy Rozental
-
Will Bryant