diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index b41ead4d170f7e8fde783f2192465d337801f18e..63349ec958705de1d0f8b9a6c432cfb9ccbd0a81 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,9 @@
+2005-01-30  Paolo Carlini  <pcarlini@suse.de>
+
+	PR libstdc++/19642
+	* config/locale/generic/c_locale.h (__convert_from_v): Switch only
+	LC_NUMERIC, and only when actually != "C".
+
 2005-01-28  Paolo Carlini  <pcarlini@suse.de>
 
 	* include/tr1/type_traits (is_function): Minor consistency tweaks.
diff --git a/libstdc++-v3/config/locale/generic/c_locale.h b/libstdc++-v3/config/locale/generic/c_locale.h
index a1a568686136061afb2e9aa2cdb9cf6e891c97c5..7b2282b04f658774bf4643bd179bd7215db3862d 100644
--- a/libstdc++-v3/config/locale/generic/c_locale.h
+++ b/libstdc++-v3/config/locale/generic/c_locale.h
@@ -59,18 +59,26 @@ namespace std
 		     const char* __fmt,
 		     _Tv __v, const __c_locale&, int __prec)
     {
-      char* __old = std::setlocale(LC_ALL, NULL);
-      char* __sav = new char[std::strlen(__old) + 1];
-      std::strcpy(__sav, __old);
-      std::setlocale(LC_ALL, "C");
+      char* __old = std::setlocale(LC_NUMERIC, NULL);
+      char* __sav = NULL;
+      if (std::strcmp(__old, "C"))
+	{
+	  __sav = new char[std::strlen(__old) + 1];
+	  std::strcpy(__sav, __old);
+	  std::setlocale(LC_NUMERIC, "C");
+	}
 
 #ifdef _GLIBCXX_USE_C99
       const int __ret = std::snprintf(__out, __size, __fmt, __prec, __v);
 #else
       const int __ret = std::sprintf(__out, __fmt, __prec, __v);
 #endif
-      std::setlocale(LC_ALL, __sav);
-      delete [] __sav;
+      
+      if (__sav)
+	{
+	  std::setlocale(LC_NUMERIC, __sav);
+	  delete [] __sav;
+	}
       return __ret;
     }
 }