#include "pip.h" #include "piiostream.h" #include "pibytearray.h" #include "pimathbase.h" using namespace PICoutManipulators; template T toDecimal(const PIString & s) { int part = 0, exp = 0; bool negative = false, negative_exp = false, err = false, has_digit = false; T ret = 0., frac = 0., frac_delim = 1.; for (const PIChar pc: s) { char c = pc.toAscii(); switch (part) { case 0: // sign if (pc.isSpace()) continue; if (c >= '0' && c <= '9') { has_digit = true; 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') { has_digit = true; ret = ret * 10 + (c - '0'); continue; } if (c == '.' || c == ',') { part = 2; continue; } if ((c == 'e' || c == 'E') && has_digit) { part = 3; continue; } err = true; break; case 2: // fractional if (c >= '0' && c <= '9') { has_digit = true; frac = frac * 10 + (c - '0'); frac_delim *= 10.; //piCout << frac << frac_delim; //printf("%.20f %.20f\n", frac, T(c - '0') / frac_delim); continue; } if ((c == 'e' || c == 'E') && has_digit) { 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; } frac /= frac_delim; ret += frac; if (negative && has_digit) ret = -ret; if (exp > 0) { if (negative_exp) ret /= pow10((T)exp); else ret *= pow10((T)exp); } return ret; } inline void test(const PIString & s) { double av = atof(s.dataAscii()); double v = toDecimal(s); printf("\n"); piCout << s << "=" << v << av; printf("atof = %.20f\n", av); printf(" PIP = %.20f\n", v); } 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("-"); test("-0"); test("-."); test("-.0"); test(".23456123456789987654"); test("-E+100"); return 0; PITimeMeasurer tm; PIString s("1.23456789"); int cnt = 10000000; int el_o = 0, el_n = 0; double v = 0.; NO_UNUSED(v); tm.reset(); piForTimes (cnt) { v = s.toDouble(); } el_o = tm.elapsed_u(); piCout << v << el_o; tm.reset(); piForTimes (cnt) { v = toDecimal(s); } el_n = tm.elapsed_u(); piCout << v << el_n; piCout << (double)el_o / el_n; return 0; }