NAN handled incorrectly by printf(), ok by snprintf()

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

NAN handled incorrectly by printf(), ok by snprintf()

Peter Smulders-2
A "double" with value NaN or Infinity produces strange results when formatted by printf() or by sprintf(), but gives the expected result when formatted by snprintf().
From the program below you expect 3 times the same line:

#include <stdio.h>
#include <math.h>

int main()
{
  char buf[24];

  printf("%7.2f %7.2f\n",NAN, INFINITY);
  sprintf(buf,"%7.2f %7.2f",NAN,INFINITY); puts(buf);
  snprintf(buf,23,"%7.2f %7.2f",NAN,INFINITY); puts(buf);
}

However the output is:

   1.#R    1.#J
   1.#R    1.#J
    nan     inf

gcc version 5.3.0
MINGW32_NT-6.2

best wishes, Peter


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
MinGW-users mailing list
[hidden email]

This list observes the Etiquette found at
http://www.mingw.org/Mailing_Lists.
We ask that you be polite and do the same.  Disregard for the list etiquette may cause your account to be moderated.

_______________________________________________
You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users
Also: mailto:[hidden email]?subject=unsubscribe
Reply | Threaded
Open this post in threaded view
|

Re: NAN handled incorrectly by printf(), ok by snprintf()

Keith Marshall-3
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 16/03/17 13:19, Peter Smulders wrote:
> A "double" with value NaN or Infinity produces strange results when
> formatted by printf() or by sprintf(), but gives the expected result
> when formatted by snprintf().

How many times must this be asked, and answered?  Anyway, let's
summarize it one more time.

> From the program below you expect 3 times the same line:

No, I don't, (unless it's compiled with -posix, or any of the
- -std options which define __STRICT_ANSI__, or any of the feature
test macros identified below).

> #include <stdio.h>
> #include <math.h>
>
> int main()
> {
>   char buf[24];
>
>   printf("%7.2f %7.2f\n",NAN, INFINITY);
>   sprintf(buf,"%7.2f %7.2f",NAN,INFINITY); puts(buf);

In each of these cases, I expect to see whatever output Microsoft's
printf() implementation will produce.

>   snprintf(buf,23,"%7.2f %7.2f",NAN,INFINITY); puts(buf);

whereas in this case, since Microsoft don't provide snprintf(), you
get the (arguably saner) output of MinGW's implementation.

> }
>
> However the output is:
>
>    1.#R    1.#J
>    1.#R    1.#J

Which is just how Microsoft's printf() implementation will format it;
if you consider it to be weird, take it up with them.

>     nan     inf

MinGW's implementation will always format NaNs and INFs thus, and
snprintf() is always the MinGW implementation.  If you want MinGW's
implementation to replace those printf() functions which Microsoft
also provide, you must explicitly request it; compile with -posix,
or any of the ANSI -std=... options, or add one of:

  #define _GNU_SOURCE
  #define _BSD_SOURCE  /* not recommended, unless it really is */
  #define _XOPEN_SOURCE 700 /* or lesser multiples of 100 */
  #define _POSIX_C_SOURCE 200809L /* or other POSIX std value */

before you include any header.

- --
Regards,
Keith.

Public key available from keys.gnupg.net
Key fingerprint: C19E C018 1547 DE50 E1D4 8F53 C0AD 36C6 347E 5A3F
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.20 (GNU/Linux)

iQIcBAEBAgAGBQJYytrOAAoJEMCtNsY0flo/ayYQAJz/rovHu/jc9EBsp/b51w+b
MmD9dRtBUEOriX+rdB0d4ek4E1B3nqcVtWTrQonMW5FDAf0nr3uDjyJ4B7EhueGX
LLA+rCzsMEtun2a56bpFb8oQClhu3cn3x2Z7pnyucZFUpXjiLbTkjZ2x0vSr6R4B
H0qbcjDTg6H6Dz4Ufk6kNFd2yWOiOT6AXLB+JL79ZZji/PUca4mC5DaCmMGEBcxc
uqXn3ncpxJP7bNzEtdmVYRgmSIZVEBwovm3TlfYcFsEHZKU9MS+HWNfh8pMKB8oh
A9PRDXXnBA01BFPfOi7xHIWrS/zCuXor2PV2KM3wxhePpaA/sD5fW27NEdRG7oIg
/ZU0pa/D5rhzaLbbQSvNefOPxbzqIfqgQ7jBWsDCBp2c5HPwfrNvZukh06X30ED8
JeptYsyHBFmqtPEQNAKpwlp3gQgNvhtbpeyCqAAA1JvPNJp+acNtuuBix6uoI8QO
+AVjQ4U5e3QdVSEJ0wnSwTmDu/WIiL4ai9+ZU2y7SGhsFlSobNn+oGWTKR+h1JK/
i+WSguMH8nlMvyc24bR3sx/KVJCfZUVPRnhn3cUSlHJVkL6aar7ghEJpp5Rabmft
G3JnBhT1VntkyVOYopwnIYsLV9VJDxRiXVTtrlQyPHZInVnO2eq8YHBPCRqVyzHl
ai+In8QVz7JOI3a2wNZB
=TZxQ
-----END PGP SIGNATURE-----

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
MinGW-users mailing list
[hidden email]

This list observes the Etiquette found at
http://www.mingw.org/Mailing_Lists.
We ask that you be polite and do the same.  Disregard for the list etiquette may cause your account to be moderated.

_______________________________________________
You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users
Also: mailto:[hidden email]?subject=unsubscribe
Reply | Threaded
Open this post in threaded view
|

Re: NAN handled incorrectly by printf(), ok by snprintf()

Peter Smulders-2
In reply to this post by Peter Smulders-2



Thanks Keith, for the many solutions you provide.
Sorry for asking a "frequently asked question".
but I found it impossible to find anything relevant on the web.

Apparently processing the format string in printf() and friends is not
an intrinsic part of gcc, but handled at runtime

The C99 standard prescribes the layout for NaN and Infinity, but
Microsoft's runtime library does not confirm to this.
(It doesn't even confirm to its own description on msdn)

The options you describe have the desired effect,
e.g. compiling with -std=c90 or -std=c11.
But, strangely enough -std=gnu99 and -std=gnu11 result in the broken
Microsoft behaviour. I would not call that C99 with gnu "extensions",
but rather regressions. Unfortunately this is also the default for gcc.

I can't find any mention of the -posix option on the gcc website
but it works.

Thanks again



>On 16/03/17 13:19, Peter Smulders wrote:
> > A "double" with value NaN or Infinity produces strange results when
> > formatted by printf() or by sprintf(), but gives the expected result
> > when formatted by snprintf().
>
>How many times must this be asked, and answered?  Anyway, let's
>summarize it one more time.
>
> > From the program below you expect 3 times the same line:
>
>No, I don't, (unless it's compiled with -posix, or any of the
>- -std options which define __STRICT_ANSI__, or any of the feature
>test macros identified below).
>
> > #include <stdio.h>
> > #include <math.h>
> >
> > int main()
> > {
> >   char buf[24];
> >
> >   printf("%7.2f %7.2f\n",NAN, INFINITY);
> >   sprintf(buf,"%7.2f %7.2f",NAN,INFINITY); puts(buf);
>
>In each of these cases, I expect to see whatever output Microsoft's
>printf() implementation will produce.
>
> >   snprintf(buf,23,"%7.2f %7.2f",NAN,INFINITY); puts(buf);
>
>whereas in this case, since Microsoft don't provide snprintf(), you
>get the (arguably saner) output of MinGW's implementation.
>
> > }
> >
> > However the output is:
> >
> >    1.#R    1.#J
> >    1.#R    1.#J
>
>Which is just how Microsoft's printf() implementation will format it;
>if you consider it to be weird, take it up with them.
>
> >     nan     inf
>
>MinGW's implementation will always format NaNs and INFs thus, and
>snprintf() is always the MinGW implementation.  If you want MinGW's
>implementation to replace those printf() functions which Microsoft
>also provide, you must explicitly request it; compile with -posix,
>or any of the ANSI -std=... options, or add one of:
>
>   #define _GNU_SOURCE
>   #define _BSD_SOURCE  /* not recommended, unless it really is */
>   #define _XOPEN_SOURCE 700 /* or lesser multiples of 100 */
>   #define _POSIX_C_SOURCE 200809L /* or other POSIX std value */
>
>before you include any header.


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
MinGW-users mailing list
[hidden email]

This list observes the Etiquette found at
http://www.mingw.org/Mailing_Lists.
We ask that you be polite and do the same.  Disregard for the list etiquette may cause your account to be moderated.

_______________________________________________
You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users
Also: mailto:[hidden email]?subject=unsubscribe