[Top][All Lists]
[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.
- RE: [lmi] Problem of the week: testing a testing tool, Boutin, Wendy, 2007/01/05
- Re: [lmi] Problem of the week: testing a testing tool, Greg Chicares, 2007/01/08
- RE: [lmi] Problem of the week: testing a testing tool, Ericksberg, Richard, 2007/01/08
- RE: [lmi] Problem of the week: testing a testing tool, Ericksberg, Richard, 2007/01/10
- Re: [lmi] Problem of the week: testing a testing tool, Greg Chicares, 2007/01/18