changeset 1080:287ec78f63b4

GenericToolbox (fast c-string --> double or integer) + refactoring to be able to set structures lut into configurator + fixed missing revision bump in configurator + UT
author Benjamin Golinvaux <bgo@osimis.io>
date Mon, 21 Oct 2019 16:01:29 +0200
parents 391fb6d6905d
children 369050c846a9
files Applications/Samples/CMakeLists.txt Framework/Deprecated/Layers/DicomStructureSetSlicer.cpp Framework/Scene2D/LookupTableStyleConfigurator.cpp Framework/Scene2D/LookupTableStyleConfigurator.h Framework/Scene2D/LookupTableTextureSceneLayer.cpp Framework/Scene2D/LookupTableTextureSceneLayer.h Framework/Toolbox/GenericToolbox.cpp Framework/Toolbox/GenericToolbox.h Resources/CMake/OrthancStoneConfiguration.cmake UnitTestsSources/GenericToolboxTests.cpp UnitTestsSources/TestMessageBroker.cpp
diffstat 11 files changed, 4254 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- a/Applications/Samples/CMakeLists.txt	Wed Oct 16 15:43:21 2019 +0200
+++ b/Applications/Samples/CMakeLists.txt	Mon Oct 21 16:01:29 2019 +0200
@@ -231,6 +231,7 @@
 if (ENABLE_NATIVE)
   add_executable(UnitTests
     ${GOOGLE_TEST_SOURCES}
+    ${ORTHANC_STONE_ROOT}/UnitTestsSources/GenericToolboxTests.cpp
     ${ORTHANC_STONE_ROOT}/UnitTestsSources/TestCommands.cpp
     ${ORTHANC_STONE_ROOT}/UnitTestsSources/TestMessageBroker.cpp
     ${ORTHANC_STONE_ROOT}/UnitTestsSources/TestStrategy.cpp
--- a/Framework/Deprecated/Layers/DicomStructureSetSlicer.cpp	Wed Oct 16 15:43:21 2019 +0200
+++ b/Framework/Deprecated/Layers/DicomStructureSetSlicer.cpp	Mon Oct 21 16:01:29 2019 +0200
@@ -18,7 +18,6 @@
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  **/
 
-
 #include "DicomStructureSetSlicer.h"
 
 namespace Deprecated
--- a/Framework/Scene2D/LookupTableStyleConfigurator.cpp	Wed Oct 16 15:43:21 2019 +0200
+++ b/Framework/Scene2D/LookupTableStyleConfigurator.cpp	Mon Oct 21 16:01:29 2019 +0200
@@ -25,6 +25,17 @@
 
 namespace OrthancStone
 {
+  static void StringToVector(std::vector<uint8_t>& target,
+    const std::string& source)
+  {
+    target.resize(source.size());
+
+    for (size_t i = 0; i < source.size(); i++)
+    {
+      target[i] = source[i];
+    }
+  }
+
   LookupTableStyleConfigurator::LookupTableStyleConfigurator() :
     revision_(0),
     hasLut_(false),
@@ -32,21 +43,28 @@
   {
   }
 
-
   void LookupTableStyleConfigurator::SetLookupTable(Orthanc::EmbeddedResources::FileResourceId resource)
   {
     hasLut_ = true;
-    Orthanc::EmbeddedResources::GetFileResource(lut_, resource);
+    std::string tmp;
+    Orthanc::EmbeddedResources::GetFileResource(tmp, resource);
+    SetLookupTable(tmp);
   }
 
+  void LookupTableStyleConfigurator::SetLookupTable(const std::vector<uint8_t>& lut)
+  {
+    hasLut_ = true;
+    lut_ = lut;
+    revision_++;
+  }
 
   void LookupTableStyleConfigurator::SetLookupTable(const std::string& lut)
   {
-    hasLut_ = true;
-    lut_ = lut;
+    std::vector<uint8_t> tmp;
+    StringToVector(tmp, lut);
+    SetLookupTable(tmp);
   }
 
-
   void LookupTableStyleConfigurator::SetRange(float minValue,
                                               float maxValue)
   {
@@ -56,19 +74,19 @@
     }
     else
     {
+      if ((!hasRange_) || (minValue_ != minValue) || (maxValue_ != maxValue))
+        revision_++;
       hasRange_ = true;
       minValue_ = minValue;
       maxValue_ = maxValue;
     }
   }
 
-    
   TextureBaseSceneLayer* LookupTableStyleConfigurator::CreateTextureFromImage(const Orthanc::ImageAccessor& image) const
   {
     throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
   }
 
-
   void LookupTableStyleConfigurator::ApplyStyle(ISceneLayer& layer) const
   {
     LookupTableTextureSceneLayer& l = dynamic_cast<LookupTableTextureSceneLayer&>(layer);
--- a/Framework/Scene2D/LookupTableStyleConfigurator.h	Wed Oct 16 15:43:21 2019 +0200
+++ b/Framework/Scene2D/LookupTableStyleConfigurator.h	Mon Oct 21 16:01:29 2019 +0200
@@ -13,7 +13,7 @@
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Affero General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Affero General Public License
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  **/
@@ -33,13 +33,13 @@
   class LookupTableStyleConfigurator : public ILayerStyleConfigurator
   {
   private:
-    uint64_t     revision_;
-    bool         hasLut_;
-    std::string  lut_;
-    bool         hasRange_;
-    float        minValue_;
-    float        maxValue_;
-    
+    uint64_t              revision_;
+    bool                  hasLut_;
+    std::vector<uint8_t>  lut_;
+    bool                  hasRange_;
+    float                 minValue_;
+    float                 maxValue_;
+
   public:
     LookupTableStyleConfigurator();
 
@@ -47,18 +47,23 @@
 
     void SetLookupTable(const std::string& lut);
 
-    void SetRange(float minValue,
-                  float maxValue);
+    /**
+     See the SetLookupTable(const std::vector<uint8_t>& lut) method in the
+     LookupTableTextureSceneLayer class.
+     */
+    void SetLookupTable(const std::vector<uint8_t>& lut);
+
+    void SetRange(float minValue, float maxValue);
 
     virtual uint64_t GetRevision() const
     {
       return revision_;
     }
-    
+
     virtual TextureBaseSceneLayer* CreateTextureFromImage(const Orthanc::ImageAccessor& image) const;
 
     virtual TextureBaseSceneLayer* CreateTextureFromDicom(const Orthanc::ImageAccessor& frame,
-                                                          const DicomInstanceParameters& parameters) const
+      const DicomInstanceParameters& parameters) const
     {
       return parameters.CreateLookupTableTexture(frame);
     }
--- a/Framework/Scene2D/LookupTableTextureSceneLayer.cpp	Wed Oct 16 15:43:21 2019 +0200
+++ b/Framework/Scene2D/LookupTableTextureSceneLayer.cpp	Mon Oct 21 16:01:29 2019 +0200
@@ -27,18 +27,6 @@
 
 namespace OrthancStone
 {
-  static void StringToVector(std::vector<uint8_t>& target,
-                             const std::string& source)
-  {
-    target.resize(source.size());
-
-    for (size_t i = 0; i < source.size(); i++)
-    {
-      target[i] = source[i];
-    }
-  }
-
-  
   LookupTableTextureSceneLayer::LookupTableTextureSceneLayer(const Orthanc::ImageAccessor& texture)
   {
     {
@@ -129,15 +117,6 @@
     }
   }
 
-
-  void LookupTableTextureSceneLayer::SetLookupTable(const std::string& lut)
-  {
-    std::vector<uint8_t> tmp;
-    StringToVector(tmp, lut);
-    SetLookupTable(tmp);
-  }
-
-  
   void LookupTableTextureSceneLayer::SetRange(float minValue,
                                               float maxValue)
   {
--- a/Framework/Scene2D/LookupTableTextureSceneLayer.h	Wed Oct 16 15:43:21 2019 +0200
+++ b/Framework/Scene2D/LookupTableTextureSceneLayer.h	Mon Oct 21 16:01:29 2019 +0200
@@ -45,8 +45,6 @@
     // (RGBA). In the RGB case, an alpha channel will be automatically added.
     void SetLookupTable(const std::vector<uint8_t>& lut);
 
-    void SetLookupTable(const std::string& lut);
-
     void SetRange(float minValue,
                   float maxValue);
     
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Framework/Toolbox/GenericToolbox.cpp	Mon Oct 21 16:01:29 2019 +0200
@@ -0,0 +1,104 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2019 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "GenericToolbox.h"
+
+#include <boost/regex.hpp>
+
+namespace OrthancStone
+{
+  namespace GenericToolbox
+  {
+    bool GetRgbaValuesFromString(uint8_t& red, uint8_t& green, uint8_t& blue, uint8_t& alpha, const char* text)
+    {
+      boost::regex pattern(R"bgo(\s*rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)\s*)bgo");
+
+      boost::cmatch what;
+
+      if (boost::regex_match(text, what, pattern))
+      {
+        {
+          std::string redStr = what[1];
+          bool ok = StringToInteger<uint8_t>(red, redStr);
+          if (!ok)
+            return false;
+        }
+        {
+          std::string greenStr = what[2];
+          bool ok = StringToInteger<uint8_t>(green, greenStr);
+          if (!ok)
+            return false;
+        }
+        {
+          std::string blueStr = what[3];
+          bool ok = StringToInteger<uint8_t>(blue, blueStr);
+          if (!ok)
+            return false;
+        }
+        {
+          std::string alphaStr = what[4];
+          bool ok = StringToInteger<uint8_t>(alpha, alphaStr);
+          if (!ok)
+            return false;
+        }
+        return true;
+      }
+      else
+      {
+        return false;
+      }
+    }
+    bool GetRgbValuesFromString(uint8_t& red, uint8_t& green, uint8_t& blue, const char* text)
+    {
+      boost::regex pattern(R"bgo(\s*rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)\s*)bgo");
+
+      boost::cmatch what;
+
+      if (boost::regex_match(text, what, pattern))
+      {
+        {
+          std::string redStr = what[1];
+          bool ok = StringToInteger<uint8_t>(red, redStr);
+          if (!ok)
+            return false;
+        }
+        {
+          std::string greenStr = what[2];
+          bool ok = StringToInteger<uint8_t>(green, greenStr);
+          if (!ok)
+            return false;
+        }
+        {
+          std::string blueStr = what[3];
+          bool ok = StringToInteger<uint8_t>(blue, blueStr);
+          if (!ok)
+            return false;
+        }
+        return true;
+      }
+      else
+      {
+        return false;
+      }
+    }
+
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Framework/Toolbox/GenericToolbox.h	Mon Oct 21 16:01:29 2019 +0200
@@ -0,0 +1,195 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2019 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Affero General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#pragma once
+
+#include <string>
+
+namespace OrthancStone
+{
+  namespace GenericToolbox
+  {
+    inline bool LegitDoubleString(const char* text)
+    {
+      const char* p = text;
+      if(*p == '-')
+        p++;
+      size_t period = 0;
+      while(*p != 0)
+      {
+        if (*p >= '0' && *p <= '9')
+          ++p;
+        else if(*p == '.')
+        {
+          if(period > 0)
+            return false;
+          else
+            period++;
+        ++p;
+        }
+        else
+          return false;
+      }
+      return true;
+    }
+
+    inline bool LegitIntegerString(const char* text)
+    {
+      const char* p = text;
+      if (*p == '-')
+        p++;
+      while (*p != 0)
+      {
+        if (*p >= '0' && *p <= '9')
+          ++p;
+        else
+          return false;
+      }
+      return true;
+    }
+
+    /*
+      String to doubles with at most 18 digits
+    */
+    inline bool StringToDouble(double& r, const char* text)
+    {
+      if(!LegitDoubleString(text))
+        return false;
+
+      static const double FRAC_FACTORS[] = 
+      {
+        1.0,
+        0.1,
+        0.01,
+        0.001,
+        0.0001,
+        0.00001,
+        0.000001,
+        0.0000001,
+        0.00000001,
+        0.000000001,
+        0.0000000001,
+        0.00000000001,
+        0.000000000001,
+        0.0000000000001,
+        0.00000000000001,
+        0.000000000000001,
+        0.0000000000000001,
+        0.00000000000000001,
+        0.000000000000000001,
+        0.0000000000000000001
+      };
+      const size_t FRAC_FACTORS_LEN = sizeof(FRAC_FACTORS)/sizeof(double);
+
+      r = 0.0;
+      double neg = 1.0;
+      const char* p = text;
+
+      if (*p == '-')
+      {
+        neg = -1.0;
+        ++p;
+      }
+      // 12345.67890
+      while (*p >= '0' && *p <= '9')
+      {
+          r = (r*10.0) + (*p - '0'); // 1 12 123 123 12345
+        ++p;
+      }
+      if (*p == '.')
+      {
+        double f = 0.0;
+        int n = 1;
+        ++p;
+        while (*p >= '0' && *p <= '9' && n < FRAC_FACTORS_LEN)
+        {
+          f += (*p - '0') * FRAC_FACTORS[n];
+          ++p;
+          ++n;
+        }
+        r += f;
+      }
+      r *= neg;
+      if (*p == 0 || (*p >= '0' && *p <= '9') )
+        return true;
+      else
+        return false;
+    }
+
+    inline bool StringToDouble(double& r, const std::string& text)
+    {
+      return StringToDouble(r, text.c_str());
+    }
+
+    template<typename T>
+    inline bool StringToInteger(T& r, const char* text)
+    {
+      if (!LegitDoubleString(text))
+        return false;
+
+      r = 0;
+      T neg = 1;
+      const char* p = text;
+
+      if (*p == '-')
+      {
+        neg = -1;
+        ++p;
+      }
+      while (*p >= '0' && *p <= '9')
+      {
+        r = (r * 10) + (*p - '0'); // 1 12 123 123 12345
+        ++p;
+      }
+      r *= neg;
+      if (*p == 0)
+        return true;
+      else
+        return false;
+    }
+
+    template<typename T>
+    inline bool StringToInteger(T& r, const std::string& text)
+    {
+      return StringToInteger<T>(r, text.c_str());
+    }
+
+    /**
+    "rgb(12,23,255)"  --> red, green, blue and returns true
+    "everything else" --> returns false (other values left untouched)
+    */
+    bool GetRgbValuesFromString(uint8_t& red, uint8_t& green, uint8_t& blue, const char* text);
+
+    /**
+    See other overload
+    */
+    inline bool GetRgbValuesFromString(uint8_t& red, uint8_t& green, uint8_t& blue, const std::string& text)
+    {
+      return GetRgbValuesFromString(red, green, blue, text.c_str());
+    }
+
+    bool GetRgbaValuesFromString(uint8_t& red, uint8_t& green, uint8_t& blue, uint8_t& alpha, const char* text);
+
+    inline bool GetRgbaValuesFromString(uint8_t& red, uint8_t& green, uint8_t& blue, uint8_t& alpha, const std::string& text)
+    {
+      return GetRgbaValuesFromString(red, green, blue, alpha, text.c_str());
+    }
+  }
+}
--- a/Resources/CMake/OrthancStoneConfiguration.cmake	Wed Oct 16 15:43:21 2019 +0200
+++ b/Resources/CMake/OrthancStoneConfiguration.cmake	Mon Oct 21 16:01:29 2019 +0200
@@ -571,6 +571,8 @@
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/SubvoxelReader.h
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/UndoRedoStack.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/UndoRedoStack.h
+  ${ORTHANC_STONE_ROOT}/Framework/Toolbox/GenericToolbox.cpp
+  ${ORTHANC_STONE_ROOT}/Framework/Toolbox/GenericToolbox.h
   
   ${ORTHANC_STONE_ROOT}/Framework/Viewport/IViewport.h
   ${ORTHANC_STONE_ROOT}/Framework/Viewport/ViewportBase.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UnitTestsSources/GenericToolboxTests.cpp	Mon Oct 21 16:01:29 2019 +0200
@@ -0,0 +1,3906 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2019 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include <Framework/Toolbox/GenericToolbox.h>
+
+#include "gtest/gtest.h"
+
+#include "stdint.h"
+
+TEST(GenericToolbox, TestLegitDoubleString)
+{
+  using OrthancStone::GenericToolbox::LegitDoubleString;
+
+  EXPECT_TRUE(LegitDoubleString("12.34"));
+  EXPECT_TRUE(LegitDoubleString("1234"));
+  EXPECT_TRUE(LegitDoubleString(".1234"));
+  EXPECT_TRUE(LegitDoubleString("1234."));
+  EXPECT_TRUE(LegitDoubleString("0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011234"));
+  EXPECT_TRUE(LegitDoubleString("000000000000000000000000000000000000000000000000000000000000000000000000000000000000.00000000000000000000000011234"));
+  EXPECT_TRUE(LegitDoubleString("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000112.34"));
+  EXPECT_TRUE(LegitDoubleString("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011234."));
+  EXPECT_TRUE(LegitDoubleString("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001123456"));
+  EXPECT_TRUE(LegitDoubleString("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001123456000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011234000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011230000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000112345000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011234000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011234565664565623456"));
+  EXPECT_TRUE(LegitDoubleString("1234."));
+  EXPECT_TRUE(LegitDoubleString(".0123"));
+  EXPECT_TRUE(LegitDoubleString(".123"));
+  EXPECT_TRUE(LegitDoubleString(".5"));
+  EXPECT_TRUE(LegitDoubleString("."));
+  EXPECT_TRUE(LegitDoubleString(""));
+  EXPECT_TRUE(LegitDoubleString("0."));
+  EXPECT_TRUE(LegitDoubleString(".0"));
+
+  EXPECT_FALSE(LegitDoubleString(".5f"));
+  EXPECT_FALSE(LegitDoubleString("1e-15"));
+  EXPECT_FALSE(LegitDoubleString("1E-15"));
+  EXPECT_FALSE(LegitDoubleString("0.31E-15"));
+  EXPECT_FALSE(LegitDoubleString(".0031E-15"));
+  EXPECT_FALSE(LegitDoubleString("1e-15"));
+  EXPECT_FALSE(LegitDoubleString("1E015"));
+  EXPECT_FALSE(LegitDoubleString("0.31E015"));
+  EXPECT_FALSE(LegitDoubleString("\n.0031E015"));
+  EXPECT_FALSE(LegitDoubleString(".05f"));
+  EXPECT_FALSE(LegitDoubleString(" 1 2 "));
+  EXPECT_FALSE(LegitDoubleString(" 0.12\t"));
+  EXPECT_FALSE(LegitDoubleString(" 0.12"));
+  EXPECT_FALSE(LegitDoubleString("0.12\t"));
+  EXPECT_FALSE(LegitDoubleString("12\t"));
+  EXPECT_FALSE(LegitDoubleString(".01 23"));
+  EXPECT_FALSE(LegitDoubleString(". 123"));
+  EXPECT_FALSE(LegitDoubleString(".5 "));
+  EXPECT_FALSE(LegitDoubleString(" ."));
+  EXPECT_FALSE(LegitDoubleString("\n0."));
+}
+
+TEST(GenericToolbox, TestLegitIntegerString)
+{
+  using OrthancStone::GenericToolbox::LegitIntegerString;
+
+  EXPECT_TRUE(LegitIntegerString("1234"));
+  EXPECT_TRUE(LegitIntegerString("234"));
+  EXPECT_TRUE(LegitIntegerString("01234"));
+  EXPECT_TRUE(LegitIntegerString("12340"));
+  EXPECT_TRUE(LegitIntegerString("0000000000000011234"));
+  EXPECT_TRUE(LegitIntegerString("00000000000000011234"));
+  EXPECT_TRUE(LegitIntegerString("00000000000011234"));
+  EXPECT_TRUE(LegitIntegerString("112340000000000010"));
+  EXPECT_TRUE(LegitIntegerString("0000000000001123456"));
+  EXPECT_TRUE(LegitIntegerString("000000000000112345604565665623456"));
+  EXPECT_TRUE(LegitIntegerString(""));
+  EXPECT_TRUE(LegitIntegerString("0"));
+  EXPECT_TRUE(LegitIntegerString("00000"));
+
+  EXPECT_FALSE(LegitIntegerString(".5f"));
+  EXPECT_FALSE(LegitIntegerString("1e-15"));
+  EXPECT_FALSE(LegitIntegerString("1E-15"));
+  EXPECT_FALSE(LegitIntegerString("0.31E-15"));
+  EXPECT_FALSE(LegitIntegerString(".0031E-15"));
+  EXPECT_FALSE(LegitIntegerString("1e-15"));
+  EXPECT_FALSE(LegitIntegerString("1E015"));
+  EXPECT_FALSE(LegitIntegerString("0.31E015"));
+  EXPECT_FALSE(LegitIntegerString("\n.0031E015"));
+  EXPECT_FALSE(LegitIntegerString(".05f"));
+  EXPECT_FALSE(LegitIntegerString(" 1 2 "));
+  EXPECT_FALSE(LegitIntegerString(" 0.12\t"));
+  EXPECT_FALSE(LegitIntegerString(" 0.12"));
+  EXPECT_FALSE(LegitIntegerString("0.12\t"));
+  EXPECT_FALSE(LegitIntegerString("12\t"));
+  EXPECT_FALSE(LegitIntegerString(".01 23"));
+  EXPECT_FALSE(LegitIntegerString(". 123"));
+  EXPECT_FALSE(LegitIntegerString(".5 "));
+  EXPECT_FALSE(LegitIntegerString(" ."));
+  EXPECT_FALSE(LegitIntegerString("\n0."));
+}
+
+TEST(GenericToolbox, TestStringToDouble)
+{
+  using OrthancStone::GenericToolbox::StringToDouble;
+
+  const double TOLERANCE = 0.00000000000001;
+  double r = 0.0;
+  bool ok = StringToDouble(r, "0.0001");
+  EXPECT_TRUE(ok);
+  EXPECT_NEAR(0.0001, r, TOLERANCE);
+
+  {
+    bool ok = StringToDouble(r, "0.0001");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.0001, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.50217817069333900000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.50217817069333900000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "5.96770274105399000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(5.96770274105399000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.49521088758962000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.49521088758962000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.06201839227379000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.06201839227379000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "5.33360671999703000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(5.33360671999703000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.07639304839166000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.07639304839166000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.19287806240687400000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.19287806240687400000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.44207082838626000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.44207082838626000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.84619708036551800000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.84619708036551800000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.58091726580509000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.58091726580509000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.18073661859763000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.18073661859763000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.33045549786387000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.33045549786387000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.00272400249168000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.00272400249168000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.95337715877137000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.95337715877137000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "8.95930523708542000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(8.95930523708542000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.78847681371515000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.78847681371515000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.23601540702684000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.23601540702684000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "3.40676557671367000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(3.40676557671367000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.36110595246212700000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.36110595246212700000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.10430292945232000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.10430292945232000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.34892053003478100000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.34892053003478100000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.86871791690589000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.86871791690589000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.23477571361979100000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.23477571361979100000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.17723077954105000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.17723077954105000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-5.55533339430731000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-5.55533339430731000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.39193581722996000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.39193581722996000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.98290538242799000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.98290538242799000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.39701448187652000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.39701448187652000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.97546141973594000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.97546141973594000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.33870401451186000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.33870401451186000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.15061799435527000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.15061799435527000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.78705704115137000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.78705704115137000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.56210637202493000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.56210637202493000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-8.86139731673717000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-8.86139731673717000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "3.63169336137189000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(3.63169336137189000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.93978481744645000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.93978481744645000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.49952444717512000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.49952444717512000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.32659301981935000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.32659301981935000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.59514994228045000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.59514994228045000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.66422938111626000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.66422938111626000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.70431239624531000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.70431239624531000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.22698147029468000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.22698147029468000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.90761005965631200000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.90761005965631200000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-5.43368952065867000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-5.43368952065867000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.79510450171595000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.79510450171595000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.94081596072268000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.94081596072268000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.42019476309409300000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.42019476309409300000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.70663631642677000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.70663631642677000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.06601188243267550000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.06601188243267550000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.79928310771909400000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.79928310771909400000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.65577800860582000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.65577800860582000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.62187216187698000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.62187216187698000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.95596656702613300000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.95596656702613300000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-4.14349841191783000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-4.14349841191783000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.23732575725115000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.23732575725115000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.02522229405373000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.02522229405373000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.43364697172459700000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.43364697172459700000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.39612114240613000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.39612114240613000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.87981321512563200000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.87981321512563200000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.47459557296809400000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.47459557296809400000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.10534326849558000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.10534326849558000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.48420825457170000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.48420825457170000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.98994851457562000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.98994851457562000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.18550683277018200000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.18550683277018200000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.79951199056989300000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.79951199056989300000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.92573951347502000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.92573951347502000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.46138476058529000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.46138476058529000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.34518431607109000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.34518431607109000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.33372656820168000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.33372656820168000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.16931283159188600000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.16931283159188600000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-4.97223922802124000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-4.97223922802124000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.48394627491386000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.48394627491386000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.88861737945960600000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.88861737945960600000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.85676190081840000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.85676190081840000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.54459170417494000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.54459170417494000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.16447870264995300000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.16447870264995300000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.35795535411029000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.35795535411029000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.29431172135530300000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.29431172135530300000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.96558311276619000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.96558311276619000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.81681460880669000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.81681460880669000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-4.20509941503951000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-4.20509941503951000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.72765905661257000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.72765905661257000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.48788237089759900000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.48788237089759900000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.24947907141902000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.24947907141902000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.59005387432649000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.59005387432649000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.30370570926522000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.30370570926522000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.73638792046556000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.73638792046556000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.87789934199453800000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.87789934199453800000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.51989255137937000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.51989255137937000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.76305470679095000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.76305470679095000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.86920962997342000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.86920962997342000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.91313411328065000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.91313411328065000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.73463683758381000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.73463683758381000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.84273889473222500000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.84273889473222500000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.87403925546477700000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.87403925546477700000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-4.36964126011414000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-4.36964126011414000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.02726746648694000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.02726746648694000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.50557053097483000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.50557053097483000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.56453106035648000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.56453106035648000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.61890516636808000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.61890516636808000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.37767835277405000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.37767835277405000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.90511255527429100000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.90511255527429100000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.05929345122920000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.05929345122920000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.21311454144036000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.21311454144036000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-7.79062987304713000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-7.79062987304713000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "5.21365525338096000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(5.21365525338096000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.28348152906416000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.28348152906416000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.06610409505261000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.06610409505261000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.35302095923550200000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.35302095923550200000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.90818370281786000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.90818370281786000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "5.32125632829404000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(5.32125632829404000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.19461589112926800000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.19461589112926800000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.13206147532649300000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.13206147532649300000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.90445975568758000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.90445975568758000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.09055301456874000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.09055301456874000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.94747584830211900000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.94747584830211900000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.87479371073786000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.87479371073786000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-5.77693922561847000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-5.77693922561847000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.43857452366099000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.43857452366099000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.32571155407419000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.32571155407419000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.02598140411007480000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.02598140411007480000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.63213858956142000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.63213858956142000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.87199046737281000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.87199046737281000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.51485641768478000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.51485641768478000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.64286402800302700000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.64286402800302700000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.47677130142230000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.47677130142230000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.39498987162520000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.39498987162520000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.97846593865349600000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.97846593865349600000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "3.38696988049949000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(3.38696988049949000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.99716557343840900000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.99716557343840900000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.26983285318203300000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.26983285318203300000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.02818282704670500000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.02818282704670500000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.33995460770471000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.33995460770471000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.90961343273142000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.90961343273142000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.70545858631691000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.70545858631691000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.99837322296447000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.99837322296447000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.52931499785106000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.52931499785106000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.50600351005455000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.50600351005455000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.83191012798055900000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.83191012798055900000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.58090819604341000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.58090819604341000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.95182376827953000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.95182376827953000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-5.04199841193785000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-5.04199841193785000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-4.17938850513021000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-4.17938850513021000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.66797071567664000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.66797071567664000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "3.37221015583147000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(3.37221015583147000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-4.75673862000485000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-4.75673862000485000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.79003986824116500000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.79003986824116500000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.86020949016507000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.86020949016507000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.14082258481500000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.14082258481500000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.71685664840859000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.71685664840859000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.93998389083824300000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.93998389083824300000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.77244357996158000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.77244357996158000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.10595524850565900000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.10595524850565900000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "3.69799635213612000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(3.69799635213612000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.57971250175452400000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.57971250175452400000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.92766866933807100000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.92766866933807100000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-5.46991620588858000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-5.46991620588858000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "5.94569644123488000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(5.94569644123488000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.18859094010287000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.18859094010287000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "3.03213167005865000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(3.03213167005865000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "8.81754146434609000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(8.81754146434609000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.75897430327076600000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.75897430327076600000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.80047028975912000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.80047028975912000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.00529573224131364000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.00529573224131364000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.71024073322357000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.71024073322357000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.60642130185119000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.60642130185119000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "5.09793780927960000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(5.09793780927960000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.18560965637846000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.18560965637846000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.13078526893487000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.13078526893487000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-4.19951899215254000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-4.19951899215254000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.81885534502479000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.81885534502479000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.00480638980341000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.00480638980341000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.35315675289406200000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.35315675289406200000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.29812812014442000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.29812812014442000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.98878626408816000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.98878626408816000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.34644737073484000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.34644737073484000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.37478492823657000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.37478492823657000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.97205178784195000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.97205178784195000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-4.65165003646427000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-4.65165003646427000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.89236175545723000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.89236175545723000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "3.80366872242454000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(3.80366872242454000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "7.65465855719486000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(7.65465855719486000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.51455943741659600000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.51455943741659600000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "5.14337541345649000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(5.14337541345649000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.06909574569091000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.06909574569091000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.07698497525470000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.07698497525470000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.04223854975535000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.04223854975535000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.46422724459484000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.46422724459484000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.65888981424971000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.65888981424971000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-7.10193673069906000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-7.10193673069906000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.77638222509466500000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.77638222509466500000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.15543610545042000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.15543610545042000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.51787760900314000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.51787760900314000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.09022915694655000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.09022915694655000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.41861013154040000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.41861013154040000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.40227565288403000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.40227565288403000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.44321592617247400000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.44321592617247400000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.34090258417639000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.34090258417639000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.54291265629528700000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.54291265629528700000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.70700051509186000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.70700051509186000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-6.55072864947955000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-6.55072864947955000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.96741942560520000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.96741942560520000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "3.55202552301084000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(3.55202552301084000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.36133250863907300000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.36133250863907300000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.46513564511238000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.46513564511238000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.97424909475891000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.97424909475891000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.87005014400085000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.87005014400085000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.25552308785543000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.25552308785543000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.43365620710902500000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.43365620710902500000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.17392137573999000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.17392137573999000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-4.56870774575795000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-4.56870774575795000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.07449225479459900000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.07449225479459900000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "5.25905472211571000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(5.25905472211571000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.13708454690765000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.13708454690765000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.08223808231444500000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.08223808231444500000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.69624060459529000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.69624060459529000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.87232652840742000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.87232652840742000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.20739068103174300000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.20739068103174300000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.45449313279700600000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.45449313279700600000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.06604828436047000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.06604828436047000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.16603807756896700000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.16603807756896700000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "6.56288534361719000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(6.56288534361719000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.28481655900710000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.28481655900710000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.79412040010646300000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.79412040010646300000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.90088144503330000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.90088144503330000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.65278657648370200000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.65278657648370200000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.40305895338068000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.40305895338068000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.07193308249503000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.07193308249503000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.83752112822253600000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.83752112822253600000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.63174453257058400000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.63174453257058400000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.80163760021425000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.80163760021425000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.57922670044433000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.57922670044433000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "6.80309348037215000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(6.80309348037215000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.03658264005365000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.03658264005365000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "8.57714214650747000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(8.57714214650747000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.25657256359494300000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.25657256359494300000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.07218601388076000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.07218601388076000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.70300607815345600000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.70300607815345600000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.06822028770915030000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.06822028770915030000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.52253514473857300000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.52253514473857300000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.89211508282910000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.89211508282910000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.47331243043688000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.47331243043688000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.77190031720697000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.77190031720697000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.80704979593058400000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.80704979593058400000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.58398766715845000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.58398766715845000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.59532008540482000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.59532008540482000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.92824570343456000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.92824570343456000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.15232705272560400000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.15232705272560400000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.13670276871382500000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.13670276871382500000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.20063314286385000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.20063314286385000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.20390958339690000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.20390958339690000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.01999231401200000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.01999231401200000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-4.33696129476675000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-4.33696129476675000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.97472839619216000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.97472839619216000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.25935508044004000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.25935508044004000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "3.98737992668548000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(3.98737992668548000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "3.12647380973595000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(3.12647380973595000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.04573005673487000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.04573005673487000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.40131707240240000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.40131707240240000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-5.65350895248975000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-5.65350895248975000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.94344081509933000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.94344081509933000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.72697189247371000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.72697189247371000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-6.67990308483490000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-6.67990308483490000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.32343310660542000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.32343310660542000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.78517123090950000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.78517123090950000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "5.25849816293583000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(5.25849816293583000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.75396267700095000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.75396267700095000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.07647901824168000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.07647901824168000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.38047538070258000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.38047538070258000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.20758597742145100000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.20758597742145100000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.85537090667122100000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.85537090667122100000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.76805423797310000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.76805423797310000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.40449492713592000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.40449492713592000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.62167096457336000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.62167096457336000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "3.74002997550002000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(3.74002997550002000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.42443064164790400000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.42443064164790400000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.27951604455776900000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.27951604455776900000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.51579267322296100000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.51579267322296100000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.36457251883339000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.36457251883339000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.24583724281163800000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.24583724281163800000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.89377268220461400000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.89377268220461400000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.45674815825147000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.45674815825147000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.85885778179785000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.85885778179785000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.46665640857091000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.46665640857091000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.20955012166670000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.20955012166670000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.56901773371710000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.56901773371710000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.28236715260714000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.28236715260714000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.68701183150938000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.68701183150938000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.52491544332882000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.52491544332882000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.35369978756681100000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.35369978756681100000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.37511760913818000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.37511760913818000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.97143364160106000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.97143364160106000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.24559477959438200000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.24559477959438200000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.75423032204965000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.75423032204965000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.32370293533555300000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.32370293533555300000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.91057697616735300000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.91057697616735300000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "5.47061739750017000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(5.47061739750017000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.00584944044255000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.00584944044255000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.50109276836214000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.50109276836214000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.55007311077336000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.55007311077336000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "6.72362848947278000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(6.72362848947278000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.01151577930873910000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.01151577930873910000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.42911860719965600000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.42911860719965600000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.66111289816664900000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.66111289816664900000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.86619326895662000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.86619326895662000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.55732089555551800000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.55732089555551800000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.30341160871063000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.30341160871063000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.56416171751671000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.56416171751671000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.18594183907073900000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.18594183907073900000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.76842629255481000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.76842629255481000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.51401910241563500000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.51401910241563500000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.22475819701855600000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.22475819701855600000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.52647532265208000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.52647532265208000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.36302691626541400000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.36302691626541400000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "3.97344494357431000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(3.97344494357431000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.55983273528683000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.55983273528683000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.11831213859734000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.11831213859734000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.65912510665320000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.65912510665320000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.49382686162217300000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.49382686162217300000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.82681319206813000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.82681319206813000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.63990018376158400000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.63990018376158400000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.46190583889476000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.46190583889476000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-5.33778970852365000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-5.33778970852365000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.67479071577411000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.67479071577411000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.92524843393689500000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.92524843393689500000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-5.25880026429762000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-5.25880026429762000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.74489327613996700000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.74489327613996700000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.81221138965657700000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.81221138965657700000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.63922583575742000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.63922583575742000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.46277795175279000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.46277795175279000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.92701639727950000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.92701639727950000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.00608886511047000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.00608886511047000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.59692755566202000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.59692755566202000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-4.43660191582482000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-4.43660191582482000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.81340386111566000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.81340386111566000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.41381029424169000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.41381029424169000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.19067619994638000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.19067619994638000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.41344288416300500000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.41344288416300500000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.19449050806631000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.19449050806631000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.94346623486537000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.94346623486537000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.15222182306952000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.15222182306952000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.16597270635016000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.16597270635016000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.70800933434033500000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.70800933434033500000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.01520859362049000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.01520859362049000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.99808924291921000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.99808924291921000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.46413571523617000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.46413571523617000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.23372155013436100000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.23372155013436100000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.22220872747082200000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.22220872747082200000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.45231083327185000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.45231083327185000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.18629931302726700000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.18629931302726700000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.25902351261081000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.25902351261081000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-4.74979626491734000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-4.74979626491734000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.96938763187002300000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.96938763187002300000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.01957662295404000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.01957662295404000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-4.29052978268713000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-4.29052978268713000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.72223107008226000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.72223107008226000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.02075269473024000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.02075269473024000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.41254866425811000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.41254866425811000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-5.79485280000328000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-5.79485280000328000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.71346724218879000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.71346724218879000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.02769972220451300000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.02769972220451300000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.30840233811538300000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.30840233811538300000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.46998368658050000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.46998368658050000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.39027116095637000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.39027116095637000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-4.76287623175477000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-4.76287623175477000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.32254147772188000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.32254147772188000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.43476530791568300000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.43476530791568300000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.15293149279800000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.15293149279800000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.52187680632247000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.52187680632247000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.81464816227136000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.81464816227136000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.45410471462063000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.45410471462063000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.05770661428355000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.05770661428355000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.13365631051443000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.13365631051443000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.78752268413674000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.78752268413674000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.07653691039301000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.07653691039301000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.69590678743817200000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.69590678743817200000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.16750017237716000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.16750017237716000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.80454059859949500000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.80454059859949500000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.01080121519000000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.01080121519000000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-6.26823154211325000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-6.26823154211325000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.27168923945051000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.27168923945051000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.95882006177823000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.95882006177823000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.29782169884960000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.29782169884960000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-5.18868107998160000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-5.18868107998160000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.42221680213317000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.42221680213317000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.97658929351465000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.97658929351465000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "3.76786358453912000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(3.76786358453912000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.63996015852897000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.63996015852897000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "5.53048948235281000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(5.53048948235281000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.72713707173900000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.72713707173900000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.67678586641071000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.67678586641071000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.27938145860632000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.27938145860632000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.67198854485259000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.67198854485259000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.08448300379640000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.08448300379640000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.89200760812645600000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.89200760812645600000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "5.84610740591283000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(5.84610740591283000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.33520422865196000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.33520422865196000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.26977509689943300000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.26977509689943300000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.06556998317024000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.06556998317024000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.10187258099846900000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.10187258099846900000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.17925123727943000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.17925123727943000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "3.53744857107300000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(3.53744857107300000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.79170718052687000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.79170718052687000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.70094405912437000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.70094405912437000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.36090079790873000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.36090079790873000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.24214402582849600000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.24214402582849600000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.61857148054390100000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.61857148054390100000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-4.49681404951875000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-4.49681404951875000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.62901170744691000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.62901170744691000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-4.31812686057237000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-4.31812686057237000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.29232513324991000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.29232513324991000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-4.30415968616239000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-4.30415968616239000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.23085063327904200000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.23085063327904200000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.55328286749515200000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.55328286749515200000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.85987085857330000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.85987085857330000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.91580898949892000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.91580898949892000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.83451772893723400000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.83451772893723400000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "8.47663066417390000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(8.47663066417390000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "3.07750241770625000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(3.07750241770625000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.79888627452876900000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.79888627452876900000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "3.62390154942094000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(3.62390154942094000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.15344123017231000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.15344123017231000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.29946850732165400000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.29946850732165400000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.43195118421230900000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.43195118421230900000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.96541584823575200000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.96541584823575200000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "5.31046639376194000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(5.31046639376194000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "5.80868720295308000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(5.80868720295308000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "3.91875650345864000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(3.91875650345864000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.16383120358956700000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.16383120358956700000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.70602187714556100000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.70602187714556100000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.59908461641224000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.59908461641224000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.75777826959967000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.75777826959967000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "7.51297060665513000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(7.51297060665513000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.26428182282563100000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.26428182282563100000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.39790664337099000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.39790664337099000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.52727246472497000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.52727246472497000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "3.15622706860781000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(3.15622706860781000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-4.33838258813926000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-4.33838258813926000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.68209356689853000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.68209356689853000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.12950059731897000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.12950059731897000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.24366467557925000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.24366467557925000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.49620375847259000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.49620375847259000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.04336416841016000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.04336416841016000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.67258592218424000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.67258592218424000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.50983053528049600000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.50983053528049600000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.91671084717300400000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.91671084717300400000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-8.44023177630015000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-8.44023177630015000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "5.74048232685721000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(5.74048232685721000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.26893036021697000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.26893036021697000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.81851986861265000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.81851986861265000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.15033199581975000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.15033199581975000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.78498201393837000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.78498201393837000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.05287486584367510000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.05287486584367510000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-4.61135813076181000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-4.61135813076181000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.28026567889772000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.28026567889772000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.42191037602383000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.42191037602383000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.91926628714024000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.91926628714024000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.13695172353534000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.13695172353534000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.19234124167404000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.19234124167404000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.54749310279860000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.54749310279860000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.79683457995789900000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.79683457995789900000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.35976469553121900000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.35976469553121900000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.77036485893720200000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.77036485893720200000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "3.05245602278075000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(3.05245602278075000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "5.82693752156961000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(5.82693752156961000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.59176692084240000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.59176692084240000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.59390017044970000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.59390017044970000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.33597209441560000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.33597209441560000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.73223852215944000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.73223852215944000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.36562951036666300000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.36562951036666300000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.16083819415565000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.16083819415565000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-5.19457461912900000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-5.19457461912900000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.48993781857833000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.48993781857833000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.91089514047878000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.91089514047878000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.67713158365996000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.67713158365996000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.14929866451844800000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.14929866451844800000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.76110653286820000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.76110653286820000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.05937778946509720000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.05937778946509720000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.67737188304973000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.67737188304973000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.58425440578219000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.58425440578219000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.30491550374261000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.30491550374261000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.48379945880357000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.48379945880357000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.62987027701035800000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.62987027701035800000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.97181285150671000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.97181285150671000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.24881707556359700000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.24881707556359700000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.83925282156180000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.83925282156180000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.07567311295324000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.07567311295324000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.78919598870022000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.78919598870022000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.51240908161798000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.51240908161798000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.51275535534832000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.51275535534832000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.58920518726789000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.58920518726789000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "3.81944139206950000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(3.81944139206950000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.20584689863215000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.20584689863215000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.52387820278697400000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.52387820278697400000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.41030960929320000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.41030960929320000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.92103214885374000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.92103214885374000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-5.24231540245246000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-5.24231540245246000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.16908726665941100000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.16908726665941100000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-4.44589887686242000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-4.44589887686242000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.49069006371512000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.49069006371512000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.80650544937931100000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.80650544937931100000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.97976397104165000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.97976397104165000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.98766812819005000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.98766812819005000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.72989593663204100000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.72989593663204100000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.61947487048298000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.61947487048298000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.14305085135282200000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.14305085135282200000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.19625994631193500000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.19625994631193500000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "3.37918205114016000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(3.37918205114016000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "6.59599108171267000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(6.59599108171267000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.96455017519345000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.96455017519345000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.54659210340770000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.54659210340770000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.34333955584988000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.34333955584988000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.97945807230247000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.97945807230247000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.16309656911088000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.16309656911088000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.25046325751587000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.25046325751587000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.95513333613538000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.95513333613538000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.44180657712571200000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.44180657712571200000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-5.62068238736436000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-5.62068238736436000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.06550714914445000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.06550714914445000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.50821128944561000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.50821128944561000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.15508838007900000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.15508838007900000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.95233817795899000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.95233817795899000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.51496658163574000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.51496658163574000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.78333801715048000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.78333801715048000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.21314186040171000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.21314186040171000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.66527690284710800000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.66527690284710800000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.15441313415350000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.15441313415350000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.23491685110319000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.23491685110319000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.72724695951577000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.72724695951577000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.24050455306641300000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.24050455306641300000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.21656863480457000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.21656863480457000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.26488830552906000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.26488830552906000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "3.75588617365038000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(3.75588617365038000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.03323480544193850000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.03323480544193850000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.09120742547457650000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.09120742547457650000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-7.88263056036503000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-7.88263056036503000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.43816026309627000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.43816026309627000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-7.03193105607121000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-7.03193105607121000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.60611554369909000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.60611554369909000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-5.51585989717609000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-5.51585989717609000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.07820571638609000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.07820571638609000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.06101375865811000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.06101375865811000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.20736962161768000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.20736962161768000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.90243061828996000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.90243061828996000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.85299495975262000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.85299495975262000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.12934888152265000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.12934888152265000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.67072919212958000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.67072919212958000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.83114509924264900000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.83114509924264900000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "5.30250616100438000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(5.30250616100438000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.12093048302870000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.12093048302870000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.05552960660102000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.05552960660102000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.49292325032676000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.49292325032676000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.17400757029104000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.17400757029104000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.14267109660887000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.14267109660887000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.10546669054034000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.10546669054034000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.21371952871041700000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.21371952871041700000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "4.78156583044177000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(4.78156583044177000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.50472792044367000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.50472792044367000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.12605755507866600000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.12605755507866600000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.70371185139311000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.70371185139311000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.10053982101354000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.10053982101354000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.83624586947925000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.83624586947925000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-4.05046060224221000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-4.05046060224221000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.28157147555257100000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.28157147555257100000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.59637285322805000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.59637285322805000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.75470175557419100000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.75470175557419100000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.70838399472621000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.70838399472621000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.45654131621183000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.45654131621183000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.28443945581399000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.28443945581399000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.68823597183684000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.68823597183684000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.29650435341174000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.29650435341174000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.90134290476188000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.90134290476188000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.18487205108194000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.18487205108194000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.14778330708372000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.14778330708372000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.98574838531856000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.98574838531856000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.38116626593387000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.38116626593387000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.18109367323846900000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.18109367323846900000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.54919024558896000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.54919024558896000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-3.01819062231017000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-3.01819062231017000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.86141885135950000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.86141885135950000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.31984756442573800000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.31984756442573800000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.35256585949514000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.35256585949514000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-6.04254591090669000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-6.04254591090669000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.31151799331342300000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.31151799331342300000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.77556498660193000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.77556498660193000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "5.90371566906766000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(5.90371566906766000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.29825016398122000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.29825016398122000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.01456323654512000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.01456323654512000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-6.19305288625244000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-6.19305288625244000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.99509367627092600000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.99509367627092600000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.08519786419394440000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.08519786419394440000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.88317752752055000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.88317752752055000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "1.69592260047492000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(1.69592260047492000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-4.66260089028084000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-4.66260089028084000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.12882625389413000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.12882625389413000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.79536921500302000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.79536921500302000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-4.51399167357593000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-4.51399167357593000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-0.75817764527332300000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-0.75817764527332300000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-2.12821371262498000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-2.12821371262498000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "-1.08153732327358000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(-1.08153732327358000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "0.71608571781169600000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(0.71608571781169600000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.42004689052701000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.42004689052701000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.84542164846610000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.84542164846610000000, r, TOLERANCE);
+  }
+
+  {
+    bool ok = StringToDouble(r, "2.97822513569917000000");
+    EXPECT_TRUE(ok);
+    EXPECT_NEAR(2.97822513569917000000, r, TOLERANCE);
+  }
+}
+
+TEST(GenericToolbox, TestStringToDoubleHard)
+{
+  using OrthancStone::GenericToolbox::StringToDouble;
+  const double TOLERANCE = 0.00000000000001;
+
+  size_t i = 0;
+  const size_t COUNT = 125;
+  //const double FACTOR = 1.000000000171271211;
+  const double FACTOR = 1.71271211;
+  for (double b = DBL_EPSILON; b < DBL_MAX && i < COUNT; ++i, b *= FACTOR)
+  {
+    char txt[1024];
+    sprintf_s(txt, "%.17f", b);
+    double r = 0.0;
+    bool ok = StringToDouble(r, txt);
+    
+#if 0
+    if (ok)
+    {
+      printf("OK for txt = \"%s\" and r = %.17f\n", txt, r);
+    }
+    else
+    {
+      printf("Not ok for txt = \"%s\" and r = %.17f\n", txt, r);
+      ok = StringToDouble(r, txt);
+    }
+#endif
+
+    EXPECT_TRUE(ok);
+
+#if 0
+    if (fabs(b - r) > TOLERANCE)
+    {
+      printf("fabs(b (%.17f) - r (%.17f)) ((%.17f))  > TOLERANCE (%.17f)\n", b, r, fabs(b-r), TOLERANCE);
+    }
+#endif
+    EXPECT_NEAR(b, r, TOLERANCE);
+  }
+}
+
+TEST(GenericToolbox, TestStringToDoubleHardNeg)
+{
+  using OrthancStone::GenericToolbox::StringToDouble;
+  const double TOLERANCE = 0.00000000000001;
+
+  size_t i = 0;
+  const size_t COUNT = 125;
+  //const double FACTOR = 1.000000000171271211;
+  const double FACTOR = 1.71271211;
+  for (double b = -1.0*DBL_EPSILON; b < DBL_MAX && i < COUNT; ++i, b *= FACTOR)
+  {
+    char txt[1024];
+    sprintf_s(txt, "%.17f", b);
+    double r = 0.0;
+    bool ok = StringToDouble(r, txt);
+
+#if 0
+    if (ok)
+    {
+      printf("OK for txt = \"%s\" and r = %.17f\n", txt, r);
+    }
+    else
+    {
+      printf("Not ok for txt = \"%s\" and r = %.17f\n", txt, r);
+      ok = StringToDouble(r, txt);
+    }
+#endif
+
+    EXPECT_TRUE(ok);
+
+#if 0
+    if (fabs(b - r) > TOLERANCE)
+    {
+      printf("fabs(b (%.17f) - r (%.17f)) ((%.17f))  > TOLERANCE (%.17f)\n", b, r, fabs(b - r), TOLERANCE);
+    }
+#endif
+    EXPECT_NEAR(b, r, TOLERANCE);
+  }
+}
+
+TEST(GenericToolbox, TestStringToIntegerHard)
+{
+  using OrthancStone::GenericToolbox::StringToInteger;
+
+  size_t i = 0;
+  const size_t COUNT = 125;
+  //const double FACTOR = 1.000000000171271211;
+  const double FACTOR = 1.71271211;
+  for (double b = DBL_EPSILON; b < DBL_MAX && i < COUNT; ++i, b *= FACTOR)
+  {
+    int64_t bi = static_cast<int64_t>(b);
+    char txt[1024];
+#if (defined __clang__) || (defined __GNUC__) || ( (defined _MSC_VER) && (_MSC_VER > 1800) )
+    sprintf_s(txt, "%lld", bi);
+#elif (defined _MSC_VER)
+    sprintf_s(txt, "%I64d", bi);
+#else
+#error Please adjust for your platform
+#endif
+    int64_t r = 0;
+    bool ok = StringToInteger<int64_t>(r, txt);
+    EXPECT_TRUE(ok);
+    EXPECT_EQ(bi, r);
+#if 0
+    if (ok)
+    {
+      printf("OK for b = %.17f bi = %lld txt = \"%s\" and r = %lld\n", b, bi, txt, r);
+    }
+    else
+    {
+      printf("NOK for b = %.17f bi = %lld txt = \"%s\" and r = %lld\n", b, bi, txt,r);
+      ok = StringToInteger<int64_t>(r, txt);
+    }
+#endif
+  }
+}
+
+
+TEST(GenericToolbox, TestGetRgbValuesFromString)
+{
+  using OrthancStone::GenericToolbox::GetRgbValuesFromString;
+
+  uint8_t red = 0;
+  uint8_t green = 0;
+  uint8_t blue = 0;
+
+  EXPECT_FALSE(GetRgbValuesFromString(red, green, blue, ""));
+  EXPECT_FALSE(GetRgbValuesFromString(red, green, blue, " "));
+  EXPECT_FALSE(GetRgbValuesFromString(red, green, blue, "rgb() "));
+  EXPECT_FALSE(GetRgbValuesFromString(red, green, blue, "rgb(12,30 2563) "));
+  EXPECT_FALSE(GetRgbValuesFromString(red, green, blue, "rgb(12,30 2563,45) "));
+  EXPECT_FALSE(GetRgbValuesFromString(red, green, blue, "rgb(12,303.23,45)"));
+  EXPECT_FALSE(GetRgbValuesFromString(red, green, blue, "rgb(12,303,45 "));
+
+  ASSERT_TRUE(GetRgbValuesFromString(red, green, blue, "rgb(12,255,45)"));
+  EXPECT_EQ(12, red);
+  EXPECT_EQ(255, green);
+  EXPECT_EQ(45, blue);
+
+  ASSERT_TRUE(GetRgbValuesFromString(red, green, blue, " rgb ( 72 , 257 , 47 ) "));
+  EXPECT_EQ(72, red);
+  EXPECT_EQ(1, green); //rollover 255 --> 255, 256 --> 0, 257 --> 1,...
+  EXPECT_EQ(47, blue);
+
+  ASSERT_TRUE(GetRgbValuesFromString(red, green, blue, " rgb ( 72 , 247 , 47 ) "));
+  EXPECT_EQ(72, red);
+  EXPECT_EQ(247, green);
+  EXPECT_EQ(47, blue);
+
+  ASSERT_TRUE(GetRgbValuesFromString(red, green, blue, " rgb ( 000, 0, 000) "));
+  EXPECT_EQ(0, red);
+  EXPECT_EQ(0, green);
+  EXPECT_EQ(0, blue);
+}
--- a/UnitTestsSources/TestMessageBroker.cpp	Wed Oct 16 15:43:21 2019 +0200
+++ b/UnitTestsSources/TestMessageBroker.cpp	Mon Oct 21 16:01:29 2019 +0200
@@ -21,10 +21,10 @@
 
 #include "gtest/gtest.h"
 
-#include "Framework/Messages/MessageBroker.h"
-#include "Framework/Messages/IObservable.h"
-#include "Framework/Messages/IObserver.h"
-#include "Framework/Messages/MessageForwarder.h"
+#include "../Framework/Messages/MessageBroker.h"
+#include "../Framework/Messages/IObservable.h"
+#include "../Framework/Messages/IObserver.h"
+#include "../Framework/Messages/MessageForwarder.h"
 
 
 int testCounter = 0;