lmi
[Top][All Lists]
Advanced

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

[lmi] A printf() defect in the msvc rtl [Was: Problem of the week: testi


From: Greg Chicares
Subject: [lmi] A printf() defect in the msvc rtl [Was: Problem of the week: testing a testing tool]
Date: Fri, 05 Jan 2007 15:00:15 +0000
User-agent: Thunderbird 1.5.0.4 (Windows/20060516)

On 2007-1-5 13:02 UTC, Boutin, Wendy wrote:
> 
> - [1.#IOe+000] identifies a limit problem when converting a certain
>     type (I think)
>     http://mail.python.org/pipermail/tutor/2006-November/051290.html

It's pretty hard to find a good answer to this puzzle with a
search engine, AFAICT, but it's reasonable to guess that we've
got an abnormal floating-point value.

C99 7.19.6.1/8 prescribes
  [-]inf
  [-]infinity
  [-]nan
as the only special output styles for 'f' conversions (modulo
upper versus lower case).

You're using MinGW gcc, which uses the msvc rtl, which doesn't
follow the standard--instead, it's documented this way:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt_precision_specification.asp

However, it doesn't seem to follow its documentation, either.

Let's try to replicate this with a simple test case. You can
write a standalone program as sketched below (add the obvious
headers etc.), or use lmi's 'sandbox_test.cpp' to build with
any of the compilers we support (that's what it's there for).

    std::printf("printf: %.3e\n", 1.0 / 0.0);

That's caught at compile time by gcc--behavior that can be
circumvented as follows:

    double volatile z = 0.0;
    std::printf("printf...: %f\n", 1.0 / z);

Now, with MinGW gcc, I get "1.#INF00", which is more sensible
than our observation. Looking at the code, we find:

    std::ostringstream oss;
    oss
        << std::scientific << std::setprecision(3)
        << "[" << timer_.elapsed_usec() / z << "] "
        << z
        << " iteration" << ((1 == z) ? "" : "s") << " took "
        << timer_.elapsed_msec_str()
        ;

The difference is scientific notation and precision, so try:

    std::printf("printf...: %.3e\n", 1.0 / z);

and now MinGW gcc gives "1.#IOe+000". Thus, it's a defect in this
toolchain, and not one that the MinGW maintainers can fix. I can
only guess that "IO" is supposed to mean it's an "Input/Output"
error, though that seems a silly characterization of an error
condition for an output function. It's definitely a capital 'O'
and not the digit '0'.

I've seen this before, and that's what I found when I looked into
it years ago. I considered it worth a quick experiment to rule
out memory corruption--another plausible explanation that might
have been a valuable early warning of impending disaster.

The old borland compiler that I have lying around prints "+INF"
in both cases above. I'd hope cygwin would get it right, too, but
I don't have a current copy of it to play with.




reply via email to

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