diff --git a/stdlib/bug-strtod.c b/stdlib/bug-strtod.c
index 82e7d30..442a6dc 100644
--- a/stdlib/bug-strtod.c
+++ b/stdlib/bug-strtod.c
@@ -21,73 +21,46 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "tst-strtod.h"
+
+#define TEST_STRTOD(FSUF, FTYPE, FTOSTR, FTOSTRM, LSUF, CSUF)	      \
+static int test_strto ## FSUF (void)				      \
+{								      \
+  char buf[300];						      \
+  int cnt;							      \
+  int result = 0;						      \
+								      \
+  for (cnt = 0; cnt < 200; ++cnt)				      \
+    {								      \
+      ssize_t n;						      \
+      FTYPE f;							      \
+								      \
+      n = sprintf (buf, "%d", cnt);				      \
+      memset (buf + n, '0', cnt);				      \
+      sprintf (buf + n + cnt, ".000e-%d", cnt);			      \
+      f = strto ## FSUF (buf, NULL);				      \
+								      \
+      if (f != (FTYPE) cnt)					      \
+	{							      \
+	  char fstr[FSTRLENMAX];				      \
+	  char fcntstr[FSTRLENMAX];				      \
+	  FTOSTR (fstr, sizeof(fstr), "%" FTOSTRM "g", f);	      \
+	  FTOSTR (fcntstr, sizeof(fstr), "%" FTOSTRM "g", (FTYPE)cnt);\
+	  printf ("strto" #FSUF "(\"%s\") "			      \
+		  "failed for cnt == %d (%s instead of %s)\n",	      \
+		  buf, cnt, fstr, fcntstr);			      \
+	  result = 1;						      \
+	}							      \
+      else							      \
+	printf ( "strto" #FSUF "() fine for cnt == %d\n", cnt);	      \
+    }								      \
+  return result;						      \
+}
+
+GEN_TEST_STRTOD_FOREACH (TEST_STRTOD)
 
 int
 main (void)
 {
-  char buf[300];
-  int cnt;
-  int result = 0;
-
-  for (cnt = 0; cnt < 200; ++cnt)
-    {
-      ssize_t n;
-      float f;
-
-      n = sprintf (buf, "%d", cnt);
-      memset (buf + n, '0', cnt);
-      sprintf (buf + n + cnt, ".000e-%d", cnt);
-      f = strtof (buf, NULL);
-
-      if (f != (float) cnt)
-	{
-	  printf ("strtof(\"%s\") failed for cnt == %d (%g instead of %g)\n",
-		  buf, cnt, f, (float) cnt);
-	  result = 1;
-	}
-      else
-	printf ("strtof() fine for cnt == %d\n", cnt);
-    }
-
-  for (cnt = 0; cnt < 200; ++cnt)
-    {
-      ssize_t n;
-      double f;
-
-      n = sprintf (buf, "%d", cnt);
-      memset (buf + n, '0', cnt);
-      sprintf (buf + n + cnt, ".000e-%d", cnt);
-      f = strtod (buf, NULL);
-
-      if (f != (double) cnt)
-	{
-	  printf ("strtod(\"%s\") failed for cnt == %d (%g instead of %g)\n",
-		  buf, cnt, f, (double) cnt);
-	  result = 1;
-	}
-      else
-	printf ("strtod() fine for cnt == %d\n", cnt);
-    }
-
-  for (cnt = 0; cnt < 200; ++cnt)
-    {
-      ssize_t n;
-      long double f;
-
-      n = sprintf (buf, "%d", cnt);
-      memset (buf + n, '0', cnt);
-      sprintf (buf + n + cnt, ".000e-%d", cnt);
-      f = strtold (buf, NULL);
-
-      if (f != (long double) cnt)
-	{
-	  printf ("strtold(\"%s\") failed for cnt == %d (%Lg instead of %Lg)\n",
-		  buf, cnt, f, (long double) cnt);
-	  result = 1;
-	}
-      else
-	printf ("strtold() fine for cnt == %d\n", cnt);
-    }
-
-  return result;
+  return STRTOD_TEST_FOREACH (test_strto);
 }
diff --git a/stdlib/tst-strtod.h b/stdlib/tst-strtod.h
new file mode 100644
index 0000000..5ac1cb1
--- /dev/null
+++ b/stdlib/tst-strtod.h
@@ -0,0 +1,49 @@
+/* Common utilities for testing strtod and its derivatives.
+   This file is part of the GNU C Library.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _TST_STRTOD_H
+#define _TST_STRTOD_H
+
+#define FSTRLENMAX 128
+
+/* Splat n variants of the same test for the various strtod functions.  */
+#define GEN_TEST_STRTOD_FOREACH(mfunc)		  \
+    mfunc(  f,       float, snprintf,  "", f, f)  \
+    mfunc(  d,      double, snprintf,  "",  ,  )  \
+    mfunc( ld, long double, snprintf, "L", L, l)
+/* The arguments to the generated macros are:
+   FSUF - Function suffix
+   FTYPE - float type
+   FTOSTR - float to string func
+   FTOSTRM - Optional modifier for FTOSTR format
+   LSUF - Literal suffix
+   CSUF - C standardish suffix for many of the math functions
+*/
+
+
+
+#define STRTOD_TEST_FOREACH(mfunc, ...)	  \
+({ static int result = 0;		  \
+   result |= mfunc ## f  (__VA_ARGS__);   \
+   result |= mfunc ## d  (__VA_ARGS__);   \
+   result |= mfunc ## ld (__VA_ARGS__);   \
+   result;				  \
+})
+
+
+#endif
