Files
pip/main.cpp
2022-09-17 17:53:58 +03:00

170 lines
3.2 KiB
C++

#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 <typename T>
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<double>(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<ldouble>(s);
}
el_n = tm.elapsed_u();
piCout << v << el_n;
piCout << (double)el_o / el_n;
return 0;
}