#include "pip.h" #include "piiostream.h" #include "pibytearray.h" #include "pimathbase.h" using namespace PICoutManipulators; inline float pow10(const int & e) {return powf(10.f, e);} inline double pow10(const double & e) {return pow(10., e);} inline ldouble pow10(const ldouble & e) {return powl(10.L, e);} template T toDouble(const PIString & s) { int part = 0; bool negative = false, negative_exp = false, err = false; T ret = 0., frac = 0., frac_delim = 10., exp = 0; for (const PIChar pc: s) { char c = pc.toAscii(); switch (part) { case 0: // sign if (pc.isSpace()) continue; if (c >= '0' && c <= '9') { ret = c - '0'; part = 1; continue; } if (c == '+') { part = 1; continue; } if (c == '-') { negative = true; part = 1; continue; } if (c == '.' || c == ',') { part = 2; continue; } err = true; break; case 1: // integer if (c >= '0' && c <= '9') { ret = ret * 10 + (c - '0'); continue; } if (c == '.' || c == ',') { part = 2; continue; } if (c == 'e' || c == 'E') { part = 3; continue; } err = true; break; case 2: // fractional if (c >= '0' && c <= '9') { frac += (c - '0') / frac_delim; frac_delim *= 10; continue; } if (c == 'e' || c == 'E') { part = 3; continue; } err = true; break; case 3: // exponent with sign if (c == '+') { part = 4; continue; } if (c == '-') { negative_exp = true; part = 4; continue; } case 4: // exponent if (c >= '0' && c <= '9') { exp = (exp * 10) + (c - '0'); continue; } err = true; break; } if (err) break; } ret += frac; if (negative) ret = -ret; if (exp > 0) { if (negative_exp) ret /= pow10(exp); else ret *= pow10(exp); } return ret; } inline void test(const PIString & s) { double av = toDouble(s); double v = s.toDouble(); piCout << s << "=" << v << av; } int main(int argc, char * argv[]) { /*test(" 123 "); test("\n123 "); test("\t123 "); test(" +123 "); test(" ++123 "); test(" + 123 "); test(" -123 "); test(" --123 "); test(" - 123 "); test("123.1"); test("123 .1"); test("123 . 1"); test("123.+1"); test("123.-1"); test("123E2"); test("123E+2"); test("123E +2"); test("123E+ 2"); test("123E + 2"); test("123 E+2"); test("123 E +2"); test("123 E+ 2"); test("123 E + 2"); test("123E+2.5"); test("123.4E+2"); test("123.4.5E+2"); test("123EE+2"); test("123e+2"); test("123e++2"); test("E+2"); test("1E+2"); test("1.E+2"); test(".E+2"); test(".1E-2"); test("+E2"); test("nan"); test("inf");*/ test("1.23"); test("1,23"); test(".23"); test(",23"); PITimeMeasurer tm; PIString s("1E+600"); int cnt = 1000000; int el_o = 0, el_n = 0; ldouble v = 0.; NO_UNUSED(v); tm.reset(); piForTimes (cnt) { v = s.toLDouble(); } el_o = tm.elapsed_u(); piCout << v << el_o; tm.reset(); piForTimes (cnt) { v = toDouble(s); } el_n = tm.elapsed_u(); piCout << v << el_n; piCout << (double)el_o / el_n; return 0; }