[PATCH] D29918: Add StringRef::getAsDouble

Zachary Turner via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 13 17:11:34 PST 2017


zturner created this revision.

It's fairly cumbersome to figure out the correct way to do this if you're not familiar with the intricacies of `APFloat`, so hopefully this can help simplify the process, and it is in the same spirit as our `getAsInteger` set of functions.

I didn't add a detailed set of tests, because these are already pretty well tested in `APFloatTest.cpp`, only the most basic cases.


https://reviews.llvm.org/D29918

Files:
  llvm/include/llvm/ADT/StringRef.h
  llvm/lib/Support/StringRef.cpp
  llvm/unittests/ADT/StringRefTest.cpp


Index: llvm/unittests/ADT/StringRefTest.cpp
===================================================================
--- llvm/unittests/ADT/StringRefTest.cpp
+++ llvm/unittests/ADT/StringRefTest.cpp
@@ -852,6 +852,27 @@
   }
 }
 
+struct GetDoubleStrings {
+  const char *Str;
+  bool AllowInexact;
+  bool ShouldFail;
+  double D;
+} DoubleStrings[] = {{"0", false, false, 0.0},
+                     {"0.0", false, false, 0.0},
+                     {"-0.0", false, false, -0.0},
+                     {"123.45", false, true, 123.45},
+                     {"123.45", true, false, 123.45}};
+
+TEST(StringRefTest, getAsDouble) {
+  for (const auto &Entry : DoubleStrings) {
+    double Result;
+    StringRef S(Entry.Str);
+    EXPECT_EQ(Entry.ShouldFail, S.getAsDouble(Result, Entry.AllowInexact));
+    if (!Entry.ShouldFail)
+      EXPECT_EQ(Result, Entry.D);
+  }
+}
+
 static const char *join_input[] = { "a", "b", "c" };
 static const char join_result1[] = "a";
 static const char join_result2[] = "a:b:c";
Index: llvm/lib/Support/StringRef.cpp
===================================================================
--- llvm/lib/Support/StringRef.cpp
+++ llvm/lib/Support/StringRef.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/APFloat.h"
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/edit_distance.h"
@@ -595,6 +596,18 @@
   return false;
 }
 
+bool StringRef::getAsDouble(double &Result, bool AllowInexact) const {
+  APFloat F(0.0);
+  APFloat::opStatus Status =
+      F.convertFromString(*this, APFloat::rmNearestTiesToEven);
+  if (Status != APFloat::opOK) {
+    if (!AllowInexact || Status != APFloat::opInexact)
+      return true;
+  }
+
+  Result = F.convertToDouble();
+  return false;
+}
 
 // Implementation of StringRef hashing.
 hash_code llvm::hash_value(StringRef S) {
Index: llvm/include/llvm/ADT/StringRef.h
===================================================================
--- llvm/include/llvm/ADT/StringRef.h
+++ llvm/include/llvm/ADT/StringRef.h
@@ -514,6 +514,8 @@
       return false;
     }
 
+    bool getAsDouble(double &Result, bool AllowInexact) const;
+
     /// Parse the current string as an integer of the specified radix.  If
     /// \p Radix is specified as zero, this does radix autosensing using
     /// extended C rules: 0 is octal, 0x is hex, 0b is binary.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D29918.88282.patch
Type: text/x-patch
Size: 2447 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170214/fcd0b4e4/attachment.bin>


More information about the llvm-commits mailing list