C++ (Qt)#include <QString> class NDataTypes { public: NDataTypes() {_id = -1; _name = "";} virtual ~NDataTypes() { } qint32 id() const {return _id;} void setId(qint32 id) {_id = id;} QString name() const {return _name;} void setName(QString name) {if (name != NULL) _name = name; else _name = "";} protected: //если идентификатор равен -1, значит это либо временная переменная, либо константное значение qint32 _id; //константные или временные значения имен не имеют, только переменные. QString _name; }; class NSimpleDataTypes : public NDataTypes { public: NSimpleDataTypes() : NDataTypes() {_constValue = false;} bool constValue() const {return _constValue;} void setConstValue(bool constValue) {_constValue = constValue;} protected: //это указывает на константное значение bool _constValue; };
C++ (Qt)class NNumeric : public NSimpleDataTypes{public: NNumeric(double value = 0) : NSimpleDataTypes() { _isTypeInteger = false; setValue(value); } NNumeric(double value, bool isTypeInteger) : NSimpleDataTypes() { setisTypeInteger(isTypeInteger); setValue(value); } //целочисленное деление static NNumeric nnDiv(NNumeric a, NNumeric b) { return NNumeric(ldiv(qint32(a), qint32(b)).quot, true); } //% (остаток от целочисленного деления) static NNumeric nnMod(NNumeric a, NNumeric b) { return NNumeric(ldiv(qint32(a), qint32(b)).rem, true); } //возведение в степень static NNumeric nnPow(NNumeric a, NNumeric b) { return NNumeric(pow(double(a), double(b)), a.isTypeInteger() && b.isTypeInteger()); } //квадратный корень static NNumeric nnSqrt(NNumeric a) { return NNumeric(sqrt(double(a)), a.isTypeInteger()); } //модуль числа static NNumeric nnAbs(NNumeric a) { return NNumeric(std::abs(double(a)), a.isTypeInteger()); } //минимальное число static NNumeric nnMin(NNumeric a, NNumeric b) { double d1 = double(a), d2 = double(b); return d1 < d2 ? NNumeric(d1, a.isTypeInteger()) : NNumeric(d2, b.isTypeInteger()); } //максимальное число static NNumeric nnMax(NNumeric a, NNumeric b) { double d1 = double(a), d2 = double(b); return d1 > d2 ? NNumeric(d1, a.isTypeInteger()) : NNumeric(d2, b.isTypeInteger()); } //десятичный логарифм static NNumeric nnLog10(NNumeric a) { return NNumeric(log10(double(a))); } //натуральный логарифм static NNumeric nnLog(NNumeric a) { return NNumeric(log(double(a))); } //экспонента в степени "a" static NNumeric nnExp(NNumeric a) { return NNumeric(exp(double(a))); } //косинус static NNumeric nnCos(NNumeric a) { return NNumeric(cos(double(a))); } //синус static NNumeric nnSin(NNumeric a) { return NNumeric(sin(double(a))); } //тангенс static NNumeric nnTan(NNumeric a) { return NNumeric(tan(double(a))); } //арктангенс static NNumeric nnCtan(NNumeric a) { return NNumeric(1.0 / tan(double(a))); } //арккосинус static NNumeric nnACos(NNumeric a) { return NNumeric(acos(double(a))); } //арксинус static NNumeric nnASin(NNumeric a) { return NNumeric(asin(double(a))); } //арктангенс static NNumeric nnATan(NNumeric a) { return NNumeric(atan(double(a))); } //арккатангенс static NNumeric nnACtan(NNumeric a) { return NNumeric(1.0 / atan(double(a))); } //округление в сторону нуля до целого static NNumeric nnFloor(NNumeric a) { return NNumeric(floor(double(a))); } //округление в большую сторону до целого static NNumeric nnCeil(NNumeric a) { return NNumeric(ceil(double(a))); } //округление до целого static NNumeric nnRound(NNumeric a) { return NNumeric(floor(double(a) + 0.5)); } //выделение дробной части static NNumeric nnFractional(NNumeric a) { double d = double(a); return d < 0.0 ? NNumeric(d - ceil(d)) : NNumeric(d - floor(d)); } //отсечение дробной части static NNumeric nnInteger(NNumeric a) { double d = double(a); return d < 0.0 ? NNumeric(ceil(d)) : NNumeric(floor(d)); } //целочисленный рандом от 0 и до a-1 static NNumeric nnRandom(NNumeric a) { srand ( time(NULL) ); return NNumeric(rand() % qint32(a), false); } //рандом от 0 до 1 static NNumeric nnRnd() { srand ( time(NULL) ); return NNumeric(double(rand() % 1001)/1000.0); } NNumeric operator+(NNumeric b) { return NNumeric(this->value() + b.value(), this->isTypeInteger() && b.isTypeInteger()); } NNumeric operator-(NNumeric b) { return NNumeric(this->value() - b.value(), this->isTypeInteger() && b.isTypeInteger()); } NNumeric operator*(NNumeric b) { return NNumeric(this->value() * b.value(), this->isTypeInteger() && b.isTypeInteger()); } NNumeric operator/(NNumeric b) { return NNumeric(this->value() / b.value(), this->isTypeInteger() && b.isTypeInteger()); } void operator++(int) { if (isTypeInteger()) _value = checkingInt32Borders(_value + 1); else _value = checkingFloatBorders(_value + 1); } void operator--(int) { if (isTypeInteger()) _value = checkingInt32Borders(_value - 1); else _value = checkingFloatBorders(_value - 1); } operator QString() {return QString::number(_value);} operator float() {return checkingFloatBorders(value());} operator qint32() {return checkingInt32Borders(_value);} //оператор ниже позволяет передать указателю значения из экземпляра класса operator NNumeric*() { NNumeric* pnn = new NNumeric(); pnn->setId(id()); pnn->setConstValue(constValue()); pnn->setName(name()); pnn->setisTypeInteger(isTypeInteger()); pnn->setValue(value()); return pnn; } private: long double int32Max() const {return 2147483647;} long double int32Min() const {return -2147483647;} long double floatMax() const {return 2.147483647e9;} long double floatMin() const {return 2.147483647e-9;} float checkingFloatBorders (double value) const { //В этой функции +/-inf приравниваются к max и min границам. double d = fabs(value); bool usign = value >= 0.0; if (d >= floatMax()) return (usign) ? floatMax() : -floatMax(); if (d <= floatMin() && d > 0.0) return (usign) ? floatMin() : -floatMin(); return float(value); } qint32 checkingInt32Borders(double value) const { if (value >= int32Max()) return int32Max(); if (value <= int32Min()) return int32Min(); return qint32(value); } void setisTypeInteger(bool isTypeInteger) {_isTypeInteger = isTypeInteger;} //Если истинно, то значение принимается и выдается (при печати числа на экране) // с отсечение дробной части числа и соблюдением границ типа qint32. bool isTypeInteger() const {return _isTypeInteger;} void setValue(double value) { if (isTypeInteger()) value = checkingInt32Borders(value); else value = checkingFloatBorders(value); _value = value; } double value() const {return double(checkingFloatBorders(_value));} operator double() {return double(checkingFloatBorders(value()));} double _value; bool _isTypeInteger;};
C++ (Qt)void NEngine::mathematicalOperations(ushort Modifikator){ NNumeric arg; switch (Modifikator) { //сумма case 2: theStack.push(popNumeric() + popNumeric()); break; //разность case 3: theStack.push(popNumeric() - popNumeric()); break; //умножение case 4: theStack.push(popNumeric() * popNumeric()); break; //деление case 5: theStack.push(popNumeric() / popNumeric()); break; //инкремент case 6: arg = popNumeric(); arg++; theStack.push(arg); break; //декремент case 7: arg = popNumeric(); arg--; theStack.push(arg); break; //целочисленное деление case 8: theStack.push(NNumeric::nnDiv(popNumeric(), popNumeric())); break; //% (остаток от целочисленного деления) case 9: theStack.push(NNumeric::nnMod(popNumeric(), popNumeric())); break; //возведение в степень case 10: theStack.push(NNumeric::nnPow(popNumeric(), popNumeric())); break; //квадратный корень case 11: theStack.push(NNumeric::nnSqrt(popNumeric())); break; //модуль числа case 12: theStack.push(NNumeric::nnAbs(popNumeric())); break; //минимальное число case 13: theStack.push(NNumeric::nnMin(popNumeric(), popNumeric())); break; //максимальное число case 14: theStack.push(NNumeric::nnMax(popNumeric(), popNumeric())); break; //целочисленный рандом от 0 и до m-1 case 15: theStack.push(NNumeric::nnRandom(popNumeric())); break; //log10 case 16: theStack.push(NNumeric::nnLog10(popNumeric())); break; //ln case 17: theStack.push(NNumeric::nnLog(popNumeric())); break; //exp case 18: theStack.push(NNumeric::nnExp(popNumeric())); break; //cos case 19: theStack.push(NNumeric::nnCos(popNumeric())); break; //sin case 20: theStack.push(NNumeric::nnSin(popNumeric())); break; //tg case 21: theStack.push(NNumeric::nnTan(popNumeric())); break; //ctg case 22: theStack.push(NNumeric::nnCtan(popNumeric())); break; //arccos case 23: theStack.push(NNumeric::nnACos(popNumeric())); break; //arcsin case 24: theStack.push(NNumeric::nnASin(popNumeric())); break; //arctg case 25: theStack.push(NNumeric::nnATan(popNumeric())); break; //arcctg case 26: theStack.push(NNumeric::nnACtan(popNumeric())); break; //округление в сторону нуля до целого case 27: theStack.push(NNumeric::nnFloor(popNumeric())); break; //округление в большую сторону до целого case 28: theStack.push(NNumeric::nnCeil(popNumeric())); break; //округление до целого case 29: theStack.push(NNumeric::nnRound(popNumeric())); break; //выделение дробной части case 30: theStack.push(NNumeric::nnFractional(popNumeric())); break; //отсечение дробной части case 31: theStack.push(NNumeric::nnInteger(popNumeric())); break; //рандом от 0 до 1 case 32: theStack.push(NNumeric::nnRnd()); break; }}
C++ (Qt)void NEngine::writeln(qint32 id){ NDataTypes* dt; QString str; if (id == 0) { dt = theStack.pop(); } else { dt = variables[id-1]; } if (typeid(NNumeric) == typeid(*dt)) { NNumeric numeric = *dynamic_cast<NNumeric*>(dt); str = QString(numeric); } if (typeid(NString) == typeid(*dt)) { NString string = *dynamic_cast<NString*>(dt); str = string.value(); } if (typeid(NLogical) == typeid(*dt)) { NLogical logical = *dynamic_cast<NLogical*>(dt); str = QString(logical); } delete dt; screen.setText(screen.text()+str+"<br\>");}
QHash<int, QString> idToName;QHash<QString, int> nameToID;
C++ (Qt) QString toString() const = 0;
C++ (Qt) if (typeid(NNumeric) == typeid(*dt)) { NNumeric numeric = *dynamic_cast<NNumeric*>(dt); str = QString(numeric); } if (typeid(NString) == typeid(*dt)) { NString string = *dynamic_cast<NString*>(dt); str = string.value(); } if (typeid(NLogical) == typeid(*dt)) { NLogical logical = *dynamic_cast<NLogical*>(dt); str = QString(logical); }
C++ (Qt) QString str = dt->toString();
C++ (Qt)const NNumeric * numeric = dynamic_cast<const NNumeric*> (dt);if (numeric) str = numeric->toString();else { ..
C++ (Qt)const BaseClass * base = dynamic_cast<const BaseClass *> (dt); // возможно и это не нужноif (base) str = base->toString();
C++ (Qt)class A{public: void setValue(int value) { this->value = value; }private: int value;}