PIString::toFloat/Double/LDouble own fast implementation (. and , equivalent)
PICout ldouble support PIEthernet small optimization
This commit is contained in:
232
main.cpp
232
main.cpp
@@ -1,97 +1,169 @@
|
||||
#include "pip.h"
|
||||
#include "piiostream.h"
|
||||
#include "pibytearray.h"
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include "pimathbase.h"
|
||||
|
||||
using namespace PICoutManipulators;
|
||||
|
||||
#define SZ 256
|
||||
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);}
|
||||
|
||||
class A {
|
||||
public:
|
||||
A() : id_(666) {
|
||||
arr = new int[SZ];
|
||||
piCout << "def A()" << id_ << this << arr;
|
||||
}
|
||||
A(int id) : id_(id) {
|
||||
arr = new int[SZ];
|
||||
piCout << "A(int)" << id_ << this << arr;
|
||||
}
|
||||
|
||||
A(const A & a) {
|
||||
arr = new int[SZ];
|
||||
id_ = a.id_;
|
||||
piCout << "A(A)" << id_ << this << arr;
|
||||
}
|
||||
|
||||
A(A && a) {
|
||||
std::swap(id_, a.id_);
|
||||
std::swap(arr, a.arr);
|
||||
piCout << "move A(A)" << id_ << this << arr;
|
||||
}
|
||||
|
||||
~A() {
|
||||
if (arr) {
|
||||
memset(arr, 0, SZ * 4);
|
||||
delete arr;
|
||||
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;
|
||||
}
|
||||
piCout << "~A()" << id_ << this << arr;
|
||||
//id_ = 0;
|
||||
if (err) break;
|
||||
}
|
||||
|
||||
inline A & operator =(const A & a) {
|
||||
id_ = a.id_;
|
||||
piCout << "A =" << id_ << this;
|
||||
return *this;
|
||||
ret += frac;
|
||||
if (negative) ret = -ret;
|
||||
if (exp > 0) {
|
||||
if (negative_exp) ret /= pow10(exp);
|
||||
else ret *= pow10(exp);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline A & operator =(A && a) {
|
||||
std::swap(id_, a.id_);
|
||||
std::swap(arr, a.arr);
|
||||
piCout << "move A=" << id_ << this;
|
||||
return *this;
|
||||
}
|
||||
private:
|
||||
int id_ = -1;
|
||||
int * arr = 0;
|
||||
};
|
||||
|
||||
|
||||
//class B {
|
||||
//public:
|
||||
// B() {a_ = nullptr;}
|
||||
// ~B() {if (a_) delete a_;}
|
||||
|
||||
// void setA(A && a) {
|
||||
// a_ = (A *)malloc(sizeof(a));
|
||||
// memcpy(a_, &a, sizeof(a));
|
||||
// operator delete(&a);
|
||||
// }
|
||||
// void setA(const A & a) {a_ = new A(a);}
|
||||
//private:
|
||||
// A * a_;
|
||||
//};
|
||||
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[]) {
|
||||
piCout << "pip 3.1";
|
||||
{
|
||||
PIDeque<A> v;
|
||||
//A a;
|
||||
//v.push_back(a);
|
||||
//v.push_back(std::move(a));
|
||||
v.push_back(A(1));
|
||||
v.push_back(A(2));
|
||||
v.push_back(A(3));
|
||||
}
|
||||
/*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);
|
||||
|
||||
piCout << "";
|
||||
piCout << "std";
|
||||
{
|
||||
std::vector<A> v;
|
||||
v.push_back(A(1));
|
||||
v.push_back(A(2));
|
||||
v.push_back(A(3));
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user