Mercurial > hg > orthanc-stone
diff Framework/Toolbox/GenericToolbox.h @ 1166:f68da12e852b
Added scientific notation support to StringToDouble
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Wed, 20 Nov 2019 10:47:42 +0100 |
parents | 141593f1aa88 |
children | ba08f2b0a779 91d86144fb79 |
line wrap: on
line diff
--- a/Framework/Toolbox/GenericToolbox.h Fri Nov 08 14:39:00 2019 +0100 +++ b/Framework/Toolbox/GenericToolbox.h Wed Nov 20 10:47:42 2019 +0100 @@ -22,6 +22,8 @@ #include <string> #include <stdint.h> +#include <math.h> + namespace OrthancStone { @@ -45,8 +47,25 @@ period++; ++p; } + else if (*p == 'e' || *p == 'E') + { + ++p; + if (*p == '-' || *p == '+') + ++p; + // "e+"/"E+" "e-"/"E-" or "e"/"E" must be followed by a number + if (!(*p >= '0' && *p <= '9')) + return false; + + // these must be the last in the string + while(*p >= '0' && *p <= '9') + ++p; + + return (*p == 0); + } else + { return false; + } } return true; } @@ -128,10 +147,62 @@ r += f; } r *= neg; - if (*p == 0 || (*p >= '0' && *p <= '9') ) + + // skip the remaining numbers until we reach not-a-digit (either the + // end of the string OR the scientific notation symbol) + while ((*p >= '0' && *p <= '9')) + ++p; + + if (*p == 0 ) + { return true; + } + else if ((*p == 'e') || (*p == 'E')) + { + // process the scientific notation + double sign; // no init is safe (read below) + ++p; + if (*p == '-') + { + sign = -1.0; + // point to first number + ++p; + } + else if (*p == '+') + { + sign = 1.0; + // point to first number + ++p; + } + else if (*p >= '0' && *p <= '9') + { + sign = 1.0; + } + else + { + // only a sign char or a number is allowed + return false; + } + // now p points to the absolute value of the exponent + double exp = 0; + while (*p >= '0' && *p <= '9') + { + exp = (exp * 10.0) + static_cast<double>(*p - '0'); // 1 12 123 123 12345 + ++p; + } + // now we have our exponent. put a sign on it. + exp *= sign; + double scFac = ::pow(10.0, exp); + r *= scFac; + + // only allowed symbol here is EOS + return (*p == 0); + } else + { + // not allowed return false; + } } inline bool StringToDouble(double& r, const std::string& text)