Fix documentation for folly's to<double>() method's handling of 'NaN' and unparseable...
authorMickey Phoenix <mickeyp@fb.com>
Wed, 12 Jul 2017 20:49:10 +0000 (13:49 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Wed, 12 Jul 2017 20:56:04 +0000 (13:56 -0700)
Summary:
The documentation for folly::to<double>()'s handling of unparseable inputs (including "") is incorrect.  Additionally, the documentation does not document to<double>()'s handling of the inputs "NaN", "-NaN", "inf", "infinity", "-inf", and "-infinity".

This corrects the documentation.

See https://github.com/facebook/folly/blob/3272dfdbe243e0ac02acca1dd82bc391d1da079a/folly/docs/Conv.md under the heading "Parsing floating-point types" for the incorrect documentation as rendered.

Reviewed By: yfeldblum

Differential Revision: D5367656

fbshipit-source-id: 22b38e2bb85d2e647975798360ead39eed6caae8

folly/docs/Conv.md
folly/test/ConvTest.cpp

index 7156c11607218fa44cb87540dfdb72f08c351b95..22add9e1c01f5079640e741663b58f4dd8e09166 100644 (file)
@@ -205,17 +205,63 @@ routine that works faster than `to<double>` chances are it is
 incorrect and will fail in a variety of corner cases. Using
 `to<double>` is strongly recommended.
 
-Note that if an unparsable string is passed to `to<double>` `NaN`
-is returned, which can be tested for as follows:
+Note that if the string "NaN" (with any capitalization) is passed to
+`to<double>` then `NaN` is returned, which can be tested for as follows:
 
 ``` Cpp
-    fbstring str = "not a double";
+    fbstring str = "nan"; // "NaN", "NAN", etc.
     double d = to<double>(str);
     if (std::isnan(d)) {
+      // string was a valid representation of the double value NaN
+    }
+```
+
+Note that passing "-NaN" (with any capitalization) to `to<double>` also returns
+`NaN`.
+
+Note that if the strings "inf" or "infinity" (with any capitalization) are
+passed to `to<double>` then `infinity` is returned, which can be tested for
+as follows:
+
+``` Cpp
+    fbstring str = "inf"; // "Inf", "INF", "infinity", "Infinity", etc.
+    double d = to<double>(str);
+    if (std::isinf(d)) {
+      // string was a valid representation of one of the double values +Infinity
+      // or -Infinity
+    }
+```
+
+Note that passing "-inf" or "-infinity" (with any capitalization) to
+`to<double>` returns `-infinity` rather than `+infinity`. The sign of the
+`infinity` can be tested for as follows:
+
+``` Cpp
+    fbstring str = "-inf"; // or "inf", "-Infinity", "+Infinity", etc.
+    double d = to<double>(str);
+    if (d == std::numeric_limits<double>::infinity()) {
+      // string was a valid representation of the double value +Infinity
+    } else if (d == -std::numeric_limits<double>::infinity()) {
+      // string was a valid representation of the double value -Infinity
+    }
+```
+
+Note that if an unparseable string is passed to `to<double>` then an exception
+is thrown, rather than `NaN` being returned.  This can be tested for as follows:
+
+``` Cpp
+    fbstring str = "not-a-double"; // Or "1.1.1", "", "$500.00", etc.
+    double d;
+    try {
+      d = to<double>(str);
+    } catch (const std::range_error &) {
       // string could not be parsed
     }
 ```
 
+Note that the empty string (`""`) is an unparseable value, and will cause
+`to<double>` to throw an exception.
+
 #### Non-throwing interfaces
 
 `tryTo<T>` is the non-throwing variant of `to<T>`. It returns
index 646f8a13f5a59591ade2a827db41b69ee3188e9a..3d5d0f631b7573cddf1dcc408113537e43042293 100644 (file)
@@ -605,12 +605,30 @@ TEST(Conv, StringPieceToDouble) {
   } catch (const std::range_error &) {
   }
 
+  EXPECT_TRUE(std::isnan(to<double>("nan")));
   EXPECT_TRUE(std::isnan(to<double>("NaN")));
+  EXPECT_TRUE(std::isnan(to<double>("NAN")));
+  EXPECT_TRUE(std::isnan(to<double>("-nan")));
+  EXPECT_TRUE(std::isnan(to<double>("-NaN")));
+  EXPECT_TRUE(std::isnan(to<double>("-NAN")));
+
   EXPECT_EQ(to<double>("inf"), numeric_limits<double>::infinity());
+  EXPECT_EQ(to<double>("Inf"), numeric_limits<double>::infinity());
+  EXPECT_EQ(to<double>("INF"), numeric_limits<double>::infinity());
+  EXPECT_EQ(to<double>("inF"), numeric_limits<double>::infinity());
   EXPECT_EQ(to<double>("infinity"), numeric_limits<double>::infinity());
+  EXPECT_EQ(to<double>("Infinity"), numeric_limits<double>::infinity());
+  EXPECT_EQ(to<double>("INFINITY"), numeric_limits<double>::infinity());
+  EXPECT_EQ(to<double>("iNfInItY"), numeric_limits<double>::infinity());
   EXPECT_THROW(to<double>("infinitX"), std::range_error);
   EXPECT_EQ(to<double>("-inf"), -numeric_limits<double>::infinity());
+  EXPECT_EQ(to<double>("-Inf"), -numeric_limits<double>::infinity());
+  EXPECT_EQ(to<double>("-INF"), -numeric_limits<double>::infinity());
+  EXPECT_EQ(to<double>("-inF"), -numeric_limits<double>::infinity());
   EXPECT_EQ(to<double>("-infinity"), -numeric_limits<double>::infinity());
+  EXPECT_EQ(to<double>("-Infinity"), -numeric_limits<double>::infinity());
+  EXPECT_EQ(to<double>("-INFINITY"), -numeric_limits<double>::infinity());
+  EXPECT_EQ(to<double>("-iNfInItY"), -numeric_limits<double>::infinity());
   EXPECT_THROW(to<double>("-infinitX"), std::range_error);
 }