--- perl-5.20.0/vutil.c	2014-05-26 09:34:21.000000000 -0400
+++ perl-5.20.0-patched/vutil.c	2014-06-19 09:25:19.024409700 -0400
@@ -585,11 +585,29 @@
     {
 	STRLEN len;
 
+#ifdef USE_LOCALE_NUMERIC
+	char *loc = setlocale(LC_NUMERIC, NULL);
+	if (loc) {
+		/* setlocale returns NULL on error */
+		if (loc[0] == 'C' && loc[1] == '\0') {
+			/* LC_NUMERIC is already C, nothing to do */
+			loc = NULL;
+		}
+		else {
+			loc = savepv(loc);
+			if (!setlocale(LC_NUMERIC, "C")) {
+			    /* error! do not restore locale later */
+			    Safefree(loc);
+			    loc = NULL;
+			}
+		}
+	}
+#endif
+
 	/* may get too much accuracy */ 
 	char tbuf[64];
 	SV *sv = SvNVX(ver) > 10e50 ? newSV(64) : 0;
 	char *buf;
-        STORE_NUMERIC_LOCAL_SET_STANDARD();
 	if (sv) {
 	    Perl_sv_catpvf(aTHX_ sv, "%.9"NVff, SvNVX(ver));
 	    len = SvCUR(sv);
@@ -599,7 +617,15 @@
 	    len = my_snprintf(tbuf, sizeof(tbuf), "%.9"NVff, SvNVX(ver));
 	    buf = tbuf;
 	}
-        RESTORE_NUMERIC_LOCAL();
+
+#ifdef USE_LOCALE_NUMERIC
+	if (loc) {
+	    /* restore locale */
+	    setlocale(LC_NUMERIC, loc);
+	    Safefree(loc);
+	}
+#endif
+
 	while (buf[len-1] == '0' && len > 0) len--;
 	if ( buf[len-1] == '.' ) len--; /* eat the trailing decimal */
 	version = savepvn(buf, len);
