Discussion:
*printf: work around rounding bug on Mac OS X
Bruno Haible
2017-04-22 14:28:46 UTC
Permalink
On Mac OS X, I'm seeing a test failure of vasnprintf-posix:
test-vasnprintf-posix.c:272
printf "%.0a" of 1.51 returns "0x1p+0", where "0x2p+0" is expected. This is a
bug, because POSIX [1] says:
"For the a and A conversion specifiers, if FLT_RADIX is a power of 2,
the value shall be correctly rounded to a hexadecimal floating number
with the given precision."

[1] http://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html

I'm pushing this workaround:


2017-04-22 Bruno Haible <***@clisp.org>

*printf: Work around rounding bug on Mac OS X.
* m4/printf.m4 (gl_PRINTF_DIRECTIVE_A): Test for Mac OS X 10.12 bug.
* doc/posix-functions/*printf.texi: Mention the rounding bugs of
Mac OS X and FreeBSD.
* doc/glibc-functions/*printf.texi: Likewise.

diff --git a/doc/glibc-functions/asprintf.texi b/doc/glibc-functions/asprintf.texi
index ae57d82..4baf95a 100644
--- a/doc/glibc-functions/asprintf.texi
+++ b/doc/glibc-functions/asprintf.texi
@@ -46,6 +46,10 @@ NetBSD 3.0, BeOS.
This function doesn't support the @code{'} flag on some platforms:
NetBSD 3.0, Cygwin 1.5.24.
@item
+This function does not round the argument of the @samp{a} directive correctly
+on some platforms:
+Mac OS X 10.12, FreeBSD 6.1.
+@item
printf @code{"%010f"} of NaN and Infinity yields an incorrect result (padded
with zeroes) on some platforms:
Mac OS X 10.5, FreeBSD 6.0, NetBSD 5.0, Solaris 11 2011-11, Cygwin 1.5.x.
diff --git a/doc/glibc-functions/obstack_printf.texi b/doc/glibc-functions/obstack_printf.texi
index 31e4d1e..d1caad3 100644
--- a/doc/glibc-functions/obstack_printf.texi
+++ b/doc/glibc-functions/obstack_printf.texi
@@ -52,6 +52,10 @@ NetBSD 3.0, mingw, MSVC 9, BeOS.
This function doesn't support the @code{'} flag on some platforms:
NetBSD 3.0, Cygwin 1.5.24, mingw, MSVC 9.
@item
+This function does not round the argument of the @samp{a} directive correctly
+on some platforms:
+Mac OS X 10.12, FreeBSD 6.1.
+@item
This function behaves incorrectly when a @samp{-} flag and a negative width
are specified together, on some platforms:
HP-UX 10.20.
diff --git a/doc/glibc-functions/obstack_vprintf.texi b/doc/glibc-functions/obstack_vprintf.texi
index 9cb5311..630b1e2 100644
--- a/doc/glibc-functions/obstack_vprintf.texi
+++ b/doc/glibc-functions/obstack_vprintf.texi
@@ -52,6 +52,10 @@ NetBSD 3.0, mingw, MSVC 9, BeOS.
This function doesn't support the @code{'} flag on some platforms:
NetBSD 3.0, Cygwin 1.5.24, mingw, MSVC 9.
@item
+This function does not round the argument of the @samp{a} directive correctly
+on some platforms:
+Mac OS X 10.12, FreeBSD 6.1.
+@item
This function behaves incorrectly when a @samp{-} flag and a negative width
are specified together, on some platforms:
HP-UX 10.20.
diff --git a/doc/glibc-functions/vasprintf.texi b/doc/glibc-functions/vasprintf.texi
index 05651ce..056121e 100644
--- a/doc/glibc-functions/vasprintf.texi
+++ b/doc/glibc-functions/vasprintf.texi
@@ -46,6 +46,10 @@ NetBSD 3.0, BeOS.
This function doesn't support the @code{'} flag on some platforms:
NetBSD 3.0, Cygwin 1.5.24.
@item
+This function does not round the argument of the @samp{a} directive correctly
+on some platforms:
+Mac OS X 10.12, FreeBSD 6.1.
+@item
printf @code{"%010f"} of NaN and Infinity yields an incorrect result (padded
with zeroes) on some platforms:
Mac OS X 10.5, FreeBSD 6.0, NetBSD 5.0, Solaris 11 2011-11, Cygwin 1.5.x.
diff --git a/doc/posix-functions/fprintf.texi b/doc/posix-functions/fprintf.texi
index f4a6d5e..da764de 100644
--- a/doc/posix-functions/fprintf.texi
+++ b/doc/posix-functions/fprintf.texi
@@ -46,6 +46,10 @@ NetBSD 3.0, mingw, MSVC 9, BeOS.
This function doesn't support the @code{'} flag on some platforms:
NetBSD 3.0, Cygwin 1.5.24, mingw, MSVC 9.
@item
+This function does not round the argument of the @samp{a} directive correctly
+on some platforms:
+Mac OS X 10.12, FreeBSD 6.1.
+@item
This function behaves incorrectly when a @samp{-} flag and a negative width
are specified together, on some platforms:
HP-UX 10.20.
diff --git a/doc/posix-functions/printf.texi b/doc/posix-functions/printf.texi
index 79537c9..2701cf2 100644
--- a/doc/posix-functions/printf.texi
+++ b/doc/posix-functions/printf.texi
@@ -46,6 +46,10 @@ NetBSD 3.0, mingw, MSVC 9, BeOS.
This function doesn't support the @code{'} flag on some platforms:
NetBSD 3.0, Cygwin 1.5.24, mingw, MSVC 9.
@item
+This function does not round the argument of the @samp{a} directive correctly
+on some platforms:
+Mac OS X 10.12, FreeBSD 6.1.
+@item
This function behaves incorrectly when a @samp{-} flag and a negative width
are specified together, on some platforms:
HP-UX 10.20.
diff --git a/doc/posix-functions/snprintf.texi b/doc/posix-functions/snprintf.texi
index 76c88fa..e7f2c51 100644
--- a/doc/posix-functions/snprintf.texi
+++ b/doc/posix-functions/snprintf.texi
@@ -61,6 +61,10 @@ Solaris 11 2011-11.
This function doesn't support the @code{'} flag on some platforms:
NetBSD 3.0, Cygwin 1.5.24, mingw, MSVC 9.
@item
+This function does not round the argument of the @samp{a} directive correctly
+on some platforms:
+Mac OS X 10.12, FreeBSD 6.1.
+@item
This function behaves incorrectly when a @samp{-} flag and a negative width
are specified together, on some platforms:
HP-UX 10.20.
diff --git a/doc/posix-functions/sprintf.texi b/doc/posix-functions/sprintf.texi
index 63b38bf..53a77e3 100644
--- a/doc/posix-functions/sprintf.texi
+++ b/doc/posix-functions/sprintf.texi
@@ -46,6 +46,10 @@ NetBSD 3.0, mingw, MSVC 9, BeOS.
This function doesn't support the @code{'} flag on some platforms:
NetBSD 3.0, Cygwin 1.5.24, mingw, MSVC 9.
@item
+This function does not round the argument of the @samp{a} directive correctly
+on some platforms:
+Mac OS X 10.12, FreeBSD 6.1.
+@item
This function behaves incorrectly when a @samp{-} flag and a negative width
are specified together, on some platforms:
HP-UX 10.20.
diff --git a/doc/posix-functions/vfprintf.texi b/doc/posix-functions/vfprintf.texi
index 00f103f..9ff9d16 100644
--- a/doc/posix-functions/vfprintf.texi
+++ b/doc/posix-functions/vfprintf.texi
@@ -46,6 +46,10 @@ NetBSD 3.0, mingw, MSVC 9, BeOS.
This function doesn't support the @code{'} flag on some platforms:
NetBSD 3.0, Cygwin 1.5.24, mingw, MSVC 9.
@item
+This function does not round the argument of the @samp{a} directive correctly
+on some platforms:
+Mac OS X 10.12, FreeBSD 6.1.
+@item
This function behaves incorrectly when a @samp{-} flag and a negative width
are specified together, on some platforms:
HP-UX 10.20.
diff --git a/doc/posix-functions/vprintf.texi b/doc/posix-functions/vprintf.texi
index a7bcf51..6b87b90 100644
--- a/doc/posix-functions/vprintf.texi
+++ b/doc/posix-functions/vprintf.texi
@@ -46,6 +46,10 @@ NetBSD 3.0, mingw, MSVC 9, BeOS.
This function doesn't support the @code{'} flag on some platforms:
NetBSD 3.0, Cygwin 1.5.24, mingw, MSVC 9.
@item
+This function does not round the argument of the @samp{a} directive correctly
+on some platforms:
+Mac OS X 10.12, FreeBSD 6.1.
+@item
This function behaves incorrectly when a @samp{-} flag and a negative width
are specified together, on some platforms:
HP-UX 10.20.
diff --git a/doc/posix-functions/vsnprintf.texi b/doc/posix-functions/vsnprintf.texi
index 495647f..13ac7bd 100644
--- a/doc/posix-functions/vsnprintf.texi
+++ b/doc/posix-functions/vsnprintf.texi
@@ -58,6 +58,10 @@ Solaris 11 2011-11.
This function doesn't support the @code{'} flag on some platforms:
NetBSD 3.0, Cygwin 1.5.24, mingw, MSVC 9.
@item
+This function does not round the argument of the @samp{a} directive correctly
+on some platforms:
+Mac OS X 10.12, FreeBSD 6.1.
+@item
This function behaves incorrectly when a @samp{-} flag and a negative width
are specified together, on some platforms:
HP-UX 10.20.
diff --git a/doc/posix-functions/vsprintf.texi b/doc/posix-functions/vsprintf.texi
index 723e4d5..be7ca48 100644
--- a/doc/posix-functions/vsprintf.texi
+++ b/doc/posix-functions/vsprintf.texi
@@ -46,6 +46,10 @@ NetBSD 3.0, mingw, MSVC 9, BeOS.
This function doesn't support the @code{'} flag on some platforms:
NetBSD 3.0, Cygwin 1.5.24, mingw, MSVC 9.
@item
+This function does not round the argument of the @samp{a} directive correctly
+on some platforms:
+Mac OS X 10.12, FreeBSD 6.1.
+@item
This function behaves incorrectly when a @samp{-} flag and a negative width
are specified together, on some platforms:
HP-UX 10.20.
diff --git a/m4/printf.m4 b/m4/printf.m4
index a44ac66..113cc2e 100644
--- a/m4/printf.m4
+++ b/m4/printf.m4
@@ -1,4 +1,4 @@
-# printf.m4 serial 52
+# printf.m4 serial 53
dnl Copyright (C) 2003, 2007-2017 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -489,6 +489,13 @@ int main ()
&& strcmp (buf, "0x6.0ap-2 33") != 0
&& strcmp (buf, "0xc.14p-3 33") != 0))
result |= 4;
+ /* This catches a Mac OS X 10.12.4 (Darwin 16.5) bug: it doesn't round. */
+ if (sprintf (buf, "%.0a %d", 1.51, 33, 44, 55) < 0
+ || (strcmp (buf, "0x2p+0 33") != 0
+ && strcmp (buf, "0x3p-1 33") != 0
+ && strcmp (buf, "0x6p-2 33") != 0
+ && strcmp (buf, "0xcp-3 33") != 0))
+ result |= 4;
/* This catches a FreeBSD 6.1 bug. See
<http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
if (sprintf (buf, "%010a %d", 1.0 / zero, 33, 44, 55) < 0

Loading...