lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] Unit test for C99 round()


From: Greg Chicares
Subject: Re: [lmi] Unit test for C99 round()
Date: Wed, 04 Jun 2008 02:20:12 +0000
User-agent: Thunderbird 2.0.0.14 (Windows/20080421)

On 2008-06-03 23:16Z, Vadim Zeitlin wrote:
> On Tue, 03 Jun 2008 22:54:11 +0000 Greg Chicares <address@hidden> wrote:
[...snip discussion of C99 round()...]
>  BTW, I wanted to look at this later, together with the other test failures
> (9 out of 54 tests fail for me under Linux now, although at least 2 or 3
> because of missing product files)

Unless you ask me not to within twenty-four hours, I will remove
'test_ledger' from 'Makefile.am', as I had earlier suppressed it
in 'objects.make', which says:

# 'ledger_test' was arguably a mistake.
...
excluded_unit_test_targets := \
  ledger_test \

As far as I remember, no other unit-test target needs any product
files other than 'sample.*', which 'product_files$(EXEEXT)' can
create. (That's probably true of 'ledger_test', too, but that
particular test is pretty hopeless for other reasons.)

> but maybe it's worth mentioning it now
> seeing that you seem to work on it: test_round_to outputs many, many test
> failures. To be precise:
> 
> **** 210 test errors detected; 8270 tests succeeded
> 
>  Please let me know if you're interested in the details,

Yes, I'm interested. BTW, this is completely different from the
C99 round() family:

'round_test.cpp':
  C99 round()
  always round away from zero

'round_to_test.cpp':
  round any of several ways, none of which matches C99 round()
  scale by a decimal factor: e.g.,
    "round up to next cent" or
    "round to nearest hundredth of a percent"

For 'round_to_test.cpp' on msw, I get:

  .... 8480 tests succeeded
  no errors detected

with gcc-3.4.5 and como, and the same even with borland.

Probably the 'round_to' code and tests co-evolved such that each
masks defects in the other with exactly those three compilers.
I keep saying stuff like that because I've just spent weeks
fixing code that was elaborately unit tested--but the unit tests
proved only that the code passed the tests, which isn't quite as
good as actually doing what's desired; yet the unit tests were
so very impressive in all their ponderous glory that no one
bothered to test the system. So, yes, it would be interesting to
see what 'round_to_test.cpp' spews out on GNU/Linux.

It's been eight years since I really looked at 'round_to.hpp',
but I've learned a lot since then, and today when there I see
        (RealType(0) < r)
            ? std::floor(r + 0.5)
            : std::ceil (r - 0.5)
I think "that'll fail with the fifty-third Mersenne number" [1].
There's certainly room for improvement.

My initial hypothesis would be, though, that you're exercising
a hitherto-unexplored path through the thicket of preprocessor
conditionals; if so, I'm hopeful that we can fix it easily.
Feel free to send me the undoubtedly-voluminous test output
separately at my personal address.

---------

[1] "that'll fail with the fifty-third Mersenne number"

/*
There's no deep number-theoretical reason; it's just that
IEC 60559 calls for 53 == DBL_MANT_DIG, and this number is
  11111111111111111111111111111111111111111111111111111
binary. You may mention this at parties, without attribution, to
impress others; just remember who told you. This is the failing
testcase that impelled us to reexamine the MinGW implementation.
*/

double round_broken(double r)
{
    return 0.0 < r
        ? floor(r + 0.5)
        : ceil (r - 0.5)
        ;
}

int main()
{
    double const M53 = 6361.0 * 69431.0 * 20394401.0;
    printf("%20.f\n",              M53 ); /* 9007199254740991 */
    printf("%20.f\n", round_broken(M53)); /* 9007199254740992 */

    return 0;
}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]