diff --git a/src/string.cpp b/src/string.cpp
index fde5212..2a490d1 100644
--- a/src/string.cpp
+++ b/src/string.cpp
@@ -206,7 +206,7 @@ inline
 float
 as_float( const string& func, const string& s, size_t* idx )
 {
-    return as_float_helper<float>( func, s, idx, strtof );
+    return as_float_helper<float>( func, s, idx, strtod );
 }
 
 template<>
@@ -230,7 +230,7 @@ inline
 float
 as_float( const string& func, const wstring& s, size_t* idx )
 {
-    return as_float_helper<float>( func, s, idx, wcstof );
+    return as_float_helper<float>( func, s, idx, wcstod );
 }
 
 template<>
diff --git a/test/strings/string.conversions/stof.pass.cpp b/test/strings/string.conversions/stof.pass.cpp
index 65809cb..6d80f1d 100644
--- a/test/strings/string.conversions/stof.pass.cpp
+++ b/test/strings/string.conversions/stof.pass.cpp
@@ -38,21 +38,27 @@ int main()
     idx = 0;
     try
     {
+        // 21.5p4 and p6: "call strtod [...] Throws out_of_range if strtod
+        // [...] sets errno to ERANGE".  1.e60 fits in a double, so while this
+        // does return INFINITY it shouldn't throw according to the standard.
         assert(std::stof("1.e60", &idx) == INFINITY);
-        assert(false);
+        assert(idx == 5);
     }
     catch (const std::out_of_range&)
     {
-        assert(idx == 0);
+        assert(false);
     }
     try
     {
+        // 21.5p11 and p13: "call wcstod [...] Throws out_of_range if wcstod
+        // [...] sets errno to ERANGE".  1.e60 fits in a double, so while this
+        // does return INFINITY it shouldn't throw according to the standard.
         assert(std::stof(L"1.e60", &idx) == INFINITY);
-        assert(false);
+        assert(idx == 5);
     }
     catch (const std::out_of_range&)
     {
-        assert(idx == 0);
+        assert(false);
     }
     idx = 0;
     try
