/
Alexandr_Pidkasisty
/
froma2
Обзор
Документация
Войти
/
Alexandr_Pidkasisty
/
froma2
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
libsource/LongReal_lib.cpp
1 281 строка
79 KB
Alexandr Pidkasisty
Объединил некоторые операторы if в методах: LongReal::operator*, LongReal::operator+, LongReal::operator-
16 апр 2026, 18:49
Верифицирован
16 апр 2026, 18:49
13c60e6
Код
Авторство
О чём код?
/** ���� ���� �������� ������ ���������� ������������ ����������� ��� �������������� �������������, ����������� ������� � ������������ ������������ ������������ ����������� "Free Operation Manager 2" (���������� FROMA2). **/ /****************************************************************************************************/ /****************************************************************************************************/ /*** ***/ /*** Copyright � 2025 ����������� ��������� �������� ***/ /*** ***/ /*** ������ �������� ��������� �����, ���������� ����� ������� ������������ ����������� � ***/ /*** ������������� ������������ (����� � ����������� �����������), ������������ ������������ ***/ /*** ����������� ����������� ��� �����������, ������� �������������� ����� �� �������������, ***/ /*** �����������, ���������, �������, ����������, ���������������, ����������������� �/��� ***/ /*** ������� ����� ������������ �����������, � ����� �����, ������� ��������������� ������ ***/ /*** ����������� �����������, ��� ���������� ��������� �������: ***/ /*** ***/ /*** ��������� ���� ����������� �� ��������� ����� � ������ ������� ������ ���� �������� �� ***/ /*** ��� ����� ��� �������� ����� ������� ������������ �����������. ***/ /*** ***/ /*** ������ ����������� ����������� ��������������� ���� ���ܻ, ��� �����-���� ��������, ���� ***/ /*** ���������� ��� ���������������, ������� �������� �������� �����������, ������������ �� ***/ /*** ��� ����������� ���������� � ���������� ���������, �� �� ������������� ���. �� � ����� ***/ /*** ������ ������ ��� ��������������� �� ����� ��������������� �� �����-���� �����, �� ����� ***/ /*** ��� �� ���� �����������, � ��� �����, ��� �������� ���������, ������� ��� ���� ��������, ***/ /*** ��������� ��-�� ������������� ������������ ����������� ��� ���� �������� � ����������� ***/ /*** ������������. ***/ /*** ***/ /****************************************************************************************************/ /****************************************************************************************************/ #include "LongReal_module.h" #include <limits> //#define Debug_voice // ������ ������ ���������� ����������. ����������������� ��� ������� namespace nmLongReal { /** �������� ������������� ��������� **/ const size_t sZero = 0, sOne = 1; const Dtype dZero = 0, dMask = 256; // ������� � ������� ���� (������� NaN � ������� ����������) const Etype eZero = 0, eOne = 1; const unsigned short int mant = std::numeric_limits<double>::max_digits10; // ���������� �������� ����� double, // ������������� ��� ������������� ���������� ������ LongReal � ��� ������ ����� � ����� ostream. ��� ���������� // ���������� ����, ������� ����������, ����� �������������� ��������� � ������������ ����� ��� ������ �������� // ��� �������������� ����� double � string � ������� � ����� double. const char chZero = '0'; // ������ ���� const char chPoint = '.'; // ������ ���������� ����� const char chMinus = '-'; // ������ ����� const string strNaN = "NaN"; // Not-A-Number �� ����� const string strInf = "inf"; // Infinity ������������� const string strNInf = "-inf"; // ������������ �� ������ ����� const string strZero = "0.0"; // ���� const string EmpStr = ""; // ����� } // namespace nmLongReal using namespace nmLongReal; /*********************************** ��������������� ������� ************************************************************/ string Corrector(const string& str) { /** ����� ���������� ������, ���������� �� ��������. � ������������ ������ ������������ ������ �������� �������, ������� ����� � ������ ������, ������ ���������� ������� ���������. ���������� ���� ����� � ������ ��������� **/ string tmp; // ������������ ������ size_t index = sZero; // �������, � ������� ���������� ������ �������� bool point = true; // ��������� ����� string::const_iterator cit = str.cbegin(); // ������������� �������� � ������ ������ if(*cit==chMinus) { // ���� ������ ������ ������ "�����", �� index = sOne; // ���������� ��������� ���� �� ���������� �������, tmp.push_back(*cit); // � ����� ������������ � ������ ������ ����� ������ }; for(cit = str.cbegin()+index; cit != str.cend(); cit++) { // ���� �� ���� �������� ������ if(isdigit(*cit)) tmp.push_back(*cit); // ���� ������� ������ "�����", �� ���������� ��� � ����� ����� ������ if((*cit==chPoint) && point) { // ���� ������� ������ ������ ������������� "�����", �� tmp.push_back(*cit); // ���������� �� � ����� ����� ������ � point = false; // ������������� ������ �� ������ ����������� ����� }; }; for(size_t i=index; i<tmp.length(); i++) { // � ����� ������ ���� ���� ����� � ������: if(*(tmp.begin()+index) == chZero) // ���� ������� �����, �� tmp.erase(tmp.begin()+index); // ������� ���� ������ �� ����� ������; if((*(tmp.end()-sOne) == chZero)&& (!point)) // ���� ������� ������ � ���� �� ����� ���� ������� �����, �� tmp.erase(tmp.end()-sOne); // ������� ���� ������ �� ����� ������, ����� ��������� ��� ���� }; if(tmp.empty()) { // ���� ������ ���������� ������, tmp.push_back(chPoint); // ���������� � ��� ����� }; if((index==sOne)&&(tmp.length()==sOne)) // ���� ������ ������� �� ������������� ������� � �� ����� ������, *tmp.begin() = chPoint; // ������ ���� ���������� ����� return tmp; } // Corrector /*************************************************************************************************************************/ /** **/ /** ������ ������ LongReal **/ /** **/ /*************************************************************************************************************************/ /********************************************** ������ private ********************************************************/ inline void LongReal::setzero() { /** ������ � ��������� ������� ����� "����". ���� ����� ���� � ����� ������, �� �� ��������� ��������� ������������� ����. ������������� ���� ����� ���������� ������ � �������������� ���������, ��� ��������� ������. **/ sign = false; // ���� ������� ������������� ������ NumCount = sZero; // ������������� ������ ������� ������ ���� if(digits) delete[] digits; // ���� ������ ����������, �� ������� ��� digits = nullptr; // ������������� ��������� �� ������ � nullptr exponent = MinEtype; // ����������� ���������� ���������� ��������� ����� } // LongReal::setzero inline void LongReal::setposinf() { /** ����� ������������� �������� ����� ������ ������������� �������������. **/ sign = false; // ������������� ����� NumCount = sZero; // ������������� ������ ������� ������ ���� if(digits) delete[] digits; // ���� ������ ����������, �� ������� ��� digits = nullptr; // ������������� ��������� �� ������ � nullptr exponent = MaxEtype; // ����������� ���������� ����������� ��������� ����� } // LongReal::setposinf inline void LongReal::setneginf() { /** ����� ������������� �������� ����� ������ ������������� �������������. **/ sign = true; // ������������� ����� NumCount = sZero; // ������������� ������ ������� ������ ���� if(digits) delete[] digits; // ���� ������ ����������, �� ������� ��� digits = nullptr; // ������������� ��������� �� ������ � nullptr exponent = MaxEtype; // ����������� ���������� ���������� ��������� ����� } // LongReal::setneginf inline void LongReal::setNaN() { /** ����� ������������� NaN. ���� NaN ���������� �� �������, ���������� inf. **/ sign = false; // ������������� ����� NumCount = sOne; // ������������� ������ ������� ������ ���� if(digits) delete[] digits; // ���� ������ ����������, �� ������� ��� digits = new(nothrow) Dtype[NumCount]; // �������� ������ ������� �� ������ �������� if(digits) { // ���� ������ ������� ��������, �� *digits = dMask; // ������ � ��������� ������� ������� NaN, exponent = eZero; // ����������� ���������� ���� � return; // ������� }; setposinf(); // ���� ������ �� ��������, �� ������������� inf } // LongReal::setNAN void LongReal::normalize() { /** ����� ����������� �����, ������� ��� � ���� sign * 0.d1d2...dn * 10^exponent **/ if(!digits) return; // ���� ������� ���, �� ������������� ������ size_t ZeroCount = sZero; // ������� ���������� ����� (��������) ����� � �������� ����� for(size_t i=sZero; i<NumCount; i++) { // ������� ����� ����� ����� � �������� ����� if(*(digits+i) == dZero) ZeroCount++; // ���� ��������� ����, �� ����������� ������� � else break; // ��� ������ ���� ���������, �� ����������� ���� }; if(ovrflw(exponent, -ZeroCount)) { // ��� ��������� ������������, return; // ������ ������� ������ �� ����� }; if(ZeroCount>sZero) { // ���� � �������� ����� ����� ����� ������� ���� ����, ��: size_t TmpCount = NumCount - ZeroCount; // ������������ ����� ����� ������� if(TmpCount == sZero) { // ���� ���������� ����� ����� ����� �������, �� ��� ����� ����: setzero(); // ������� ������ � ������������� ����� � ���� return; // � ������� }; Dtype* temp = new(nothrow) Dtype[TmpCount]; // �������� ������ ������ ������� if(!temp) return; // ���� ������ �� ��������, �� ������ ���������� for(size_t i=sZero; i<TmpCount; i++) // ������������ � ����� ������ ������ �� ����������� ������ ����� *(temp+i) = *(digits+i+ZeroCount); exponent -= ZeroCount; // ������ ���������� NumCount = TmpCount; // ������ ����� ������� delete[] digits; // ������� ������ ������ digits = temp; // ��������� ��������� ������� ���������� �� ����� ������ } } // LongReal::normalize inline Dtype* LongReal::cut(const Dtype _digits[], size_t Num) { /** ������� ����� ������������� ������� _digits � �������� �� � �����, �������� ��� ������ ������ Num. ���������� ���������� ����� **/ size_t Cnt = Num < NumCount ? Num : NumCount; // ������ �� ���������� Num > NumCount Dtype* temp = new(nothrow) Dtype[Cnt]; // �������� ������ ������� �������� Num if(!temp) return nullptr; // ���� ������ �� ��������, �� ����� memcpy(temp, _digits, sizeof(Dtype)*Cnt); // �������� ������ Num 'ktvtyns d yjdsq vfccbd return temp; } // LongReal::cut inline void LongReal::Resize(const size_t _n) { /** ��������� ����������� ������� digits �� ������ �������, _n - ����� ������ **/ if(_n < sOne) return; // ������������ ������ if(_n >= NumCount) return; // ������������ ������ Dtype* temp = new(nothrow) Dtype[_n]; // �������� ������ ������� �������� _n if(!temp) return; // ���� ������ �� ��������, �� ����� memcpy(temp, digits, sizeof(Dtype)*_n); // �������� ������ _n ��������� ������� std::swap(temp, digits); // ���������� ��������� delete[] temp; // ������� ��������������� ������ NumCount = _n; // ��������� } // LongReal::Resize void LongReal::init(const string& s) { /** ����� ������ �����, �������������� �������. ��������!!! ��� ����������� ���������� ������ ����������, ����� ��������� digits �������� �� �������� ������ ��� �� nullptr **/ size_t index; // ������ ������ bool backupsign = sign; // ��������� ������� ��������� ����� ����� if (*s.begin() == chMinus) { // ���� ������ ������ ������ �����, �� ����� ������������� sign = true; // ���� �������������� ����� true index = sOne; // �������� ���� ����� ����� �� � ��������, � � ������� ������� } else { sign = false; // ����� ����� ������������� index = sZero; // � ���� ����� ����� � �������� ������� }; size_t TmpCount = s.length() - index; // ���������� ����� ������� Dtype* temp = new(nothrow) Dtype[TmpCount]; // �������� ������ ������ ������� �������� TmpCount if(!temp) { // ���� ������ �� ��������, �� sign = backupsign; // ��������������� ���� ����� return; // � �������; ����� ��� ���� �� ���������� }; // ���� �� ������ �������� �������, �� NumCount = TmpCount; // ������������� ����� ����� ������� ������ TmpCount // ������������, ��� �� ����� ����� �����, � ������ � ���������� ����� ����� ����� ������ exponent = (Etype)(NumCount); // ������������� ���������� ������ ����� ������ size_t i = sZero; // ������ ������� while (index < s.length()) { // ��� �� ���� ������, if(*(s.begin()+index) == chPoint) { // ���� ��������� �����, �� exponent = (sign) ? (Etype)index-1 : (Etype)index; // ���������� ����������, ��� ��� ����� ����� �����������, i--; // ��������� ��������� ������� �� ������� } else { *(temp+i) = (Dtype)(*(s.begin()+index)-'0'); // ����������� ������ � ����� � ���������� � ������ }; index++; // ����������� ������ ������ i++; // ����������� ������ ������� }; if(digits) delete[] digits; // ���� ��������� �� ������ �� ����� nullptr, �� ������� ������ digits = LongReal::cut(temp, i); // ����������� ��������� ����� ������� temp, ������� �� �� ������� i if(!digits) { // ���� cut ������ nullptr, �� delete[] temp; // ������� ��������������� ������ sign = false; // ������������� ����� � ���� NumCount = sZero; exponent = MinEtype; return; // � ������� }; NumCount = i; // ������������� ����� ������� delete[] temp; // ������� ��������������� ������ LongReal::normalize(); // ����������� ����� } // LongReal::init stringstream LongReal::getstream() const { /** ����� ���������� �������� ����� � �����. ������������ � ��������� ������� ��� ������ ����� � ���������� ���� string, long double, double, float **/ stringstream ss; // ����� ��� �������� �� ������� if(this->isNaN()) { // �������� �� NaN ss << strNaN; // ������� NaN � ����� � return ss; // ���������� ����� }; if(sign) ss << chMinus; // ��������� ���� �����, ���� �������������, �� ������� � ����� ���� "�����" // ���� ������ � ����� ����������� � ����� ������� � ���� ����� �������, �� ��������� ���������� if(( !digits) || (NumCount==sZero)) { // ��������� ����� �� ���� � ������������� if(exponent==MinEtype) { // ��������� ��������� ����, ���� ����� - ��� ����, �� ss << strZero; // ������� ����� "����" � ����� � return ss; // ���������� ����� }; if(exponent==MaxEtype) { // ��������� ��������� ����� �������������, ���� ����� �������������, �� ss << strInf; // ������� ������������ ������������� � ����� � return ss; // ���������� ����� (���� + ��� - ������� � ����� �����) }; }; // �������� �� ���� � ������������� if(exponent > eZero) { // ���� ���������� ������������, �� � ����� ��������� ����� ����� Etype i = eZero; // �������� ������� ���� � ����� // ������� ������ exponent ���� ����� (��� ��� �����, ���� ���������� ������), while((i < (Etype)NumCount) && (i < exponent)) ss << digits[i++]; // ����� ������� ����� ����� while (i < exponent) { // ���� ���������� ������ ���� �����, ss << chZero; // �� ������� ������ ����, ����� ����� �� ���������� i++; }; if (i < (Etype)NumCount) { // ���� ����� ��� ��������, �� ss << chPoint; // ������� ����� � while(i < (Etype)NumCount) // ������� ���������� ����� ��� ������� ����� ss << digits[i++]; }; return ss; }; // ����� ��������� ������������ ��� ������� ss << chZero << chPoint; // ������� ������� ����� ����� � ������ � ����� ������� if(exponent == eZero) { // ���� ���������� �������, �� for (Etype i = eZero; i < (Etype)NumCount; i++) ss << digits[i]; // ������� ��� ����� ����� � ����� return ss; // � ������� }; if(exponent < eZero) { // ���� ���������� �������������, �� for(Etype i = eZero; i < -exponent; i++) ss << chZero; // ������� |exponent| ����� for (size_t i = sZero; i < NumCount; i++) ss << digits[i]; // ������� ��� ����� ����� � ����� return ss; // � ������� }; return ss; } // stringstream getstream inline bool LongReal::ovrflw(const Etype& E1, const Etype& E2) const { /** ���������� true, ���� ��� �������� ��������� (E1 � E2) �������� ������������ (����� �� ������� ������������� � ������������ ����� **/ if(E1>eZero && E2>eZero) // ���� ��� ����� �������������, �� ��������� ���������� ������� if(E2 > (MaxEtype-E1)) return true; // ����� ��� �������� ����� ������������ ������ � ������ ������ if(E1<eZero && E2<eZero) // ���� ��� ����� �������������, �� ��������� ���������� ������� if(E2 < (MinEtype-E1)) return true; // ����� ����������� ������ � ������ ������ ��� ������ ������ return false; } // LongReal::ovrflw LongReal LongReal::incrE(const Etype& _E) const { /** ����� ���������, ��� ����� �������� ���������� _E ������, ��� �������. ������ � ���� ������ ����� ������� ����� �������� ����������, ����������� ���������� ����� � ����� �� �������� _E �� ������� ������ ����� (����������� ���������� � ������������ ��������� ����� ����� ����� �������� ���� � ������ digits ������ �������). ��������� � ������� LongReal::incrD(...) ��������� ��������� ����� �� ���������� � �� ���������� ���� (����� ������� digits) ��� ���������� ��� ���� �������������� ��������. **/ LongReal res; // ������� �������� ������, ������ ���� if(this->isNaN()) { // �������� �� NaN res.setNaN(); // ���� ������� ��������� NaN, �� ����� ������������� � NaN return res; // � ���������� ����� � NaN }; if(*this == res) return res; // ���� ������� ��������� ����� +/- ����, �� ���������� ����� � ����� if(this->isposInf()) { // �������� �� +inf res.setposinf(); // ���� ������� ��������� inf, �� ����� ������������� � inf return res; } if(this->isnegInf()) { // �������� �� -inf res.setneginf(); // ���� ������� ��������� -inf, �� ����� ������������� � -inf return res; }; if(_E <= exponent) { // ���� ������ �������� ���������� �� ������ ��������, �� res = *this; // �������� � ��������� ����� �������� ����� ��� ��������� ����������, return res; // ������� � ���������� ����� �������� ����� } Etype dE = _E - exponent; // ��������� �������� ���������� ���������� if(ovrflw(exponent, dE)) { // �������� ������������. ���� �������� ������������, �� res.setNaN(); // ����� ������������� � NaN return res; // � ���������� ����� � NaN }; res.sign = sign; // ��������� ���� ����� � ����� ������� res.exponent = _E; // �������� ���������� � ���������� size_t NewCount = NumCount+dE; // ��������� ����� ��������������� ������� res.NumCount = NewCount; // ������������� ������ ������� Dtype* tmp = new(nothrow) Dtype[NewCount]; // �������� ������ ���������� ������� if(!tmp) { // ���� ������ �� ��������, res.setNaN(); // �� ������������� ��������� � NaN return res; // � ������� }; for(size_t i= sZero; i<(size_t)dE; i++) // ������ dE ��������� ������� *(tmp+i) = dZero; // ��������� ������ for(size_t i=(size_t)dE; i<NewCount; i++ ) // ��������� �������� *(tmp+i) = *(digits + i -(size_t)dE); // �������� �� ������ �������� ������� res.digits = tmp; // ������������� ��������� ��������� ������� �� tmp return res; // � ������� } // LongReal LongReal::incrE void LongReal::incrD(const size_t& _N) { /** ����� ����������� ����� ������� digits �������� ���������� �� �������� _N �� ���� ������ �����. ����� �� ��������. ���� ������ ������� ������ ��� ����� _N, �� ������ �� ����������. ��������� � ������� LongReal::incrE(...) ��������� ��������� ����� �� ���������� � �� ���������� ���� (����� ������� digits) ��� ���������� ��� ���� �������������� ��������.**/ if( (!digits) || (NumCount == sZero) ) return; // ���� ������ ����������� ��� ��� ����� ����� ����, �� ������ �� ������ if( (digits) && (NumCount == sOne)&& (*digits == dMask)) return; // ���� � ������� ������� NaN, �� ������ �� ������ if(_N > NumCount) { // ���� ����� ������ ������ ��������, ��: Dtype* tmp = new(nothrow) Dtype[_N]; // �������� ������ ������� if(!tmp) return; // ���� ������ �� ��������, �� ������� ��� ��������� for(size_t i=sZero; i<NumCount; i++) // �������� NumCount ��������� �� digits � ����� ������ *(tmp+i) = *(digits+i); for(size_t i=NumCount; i<_N; i++ ) // ���������� (_N-NumCount) ��������� *(tmp+i) = dZero; // ��������� ������ NumCount = _N; // ������������� ����� ����� ������ Dtype* backup = digits; // ��������� ��������� ������� ������� digits = tmp; // ������� ��������� ������������� �� ����� ������ if(backup) delete[] backup; // ������� ������ ������ }; } // Dtype LongReal::incrD LongReal LongReal::_round(const size_t _n) const { /** ���������� ����� ���� LongReal � ����������� �� _n ��������; �������� � �������� �� _n+1 �� NumCount �� ��������. ����� ������������ � ������� string Get(size_t) **/ Stype _sign = this->sign; // ���� ���������������� ����� ������ ����� ��������� size_t _NumCount = 1; // ������ ������� � ��������� ���������������� ����� Dtype* _digits = new Dtype[_NumCount]{5}; // ������� ������������ ������ � ����� ��������� Etype _exp = static_cast<Etype>(-_n); // ������� ���������� ��� ���������������� ����� const LongReal temp(_sign, _NumCount, _digits, _exp); // ������� ��������� ����� ��� ���������� return (*this + temp); // ���������� ����� ������������ ����� } // LongReal::_round /********************************************** ������ public ********************************************************/ LongReal::LongReal() { /** ����������� �� ���������. ������� ��������� ������ � ������ ���� **/ sign = false; // ���� ������� ������������� ������ NumCount = sZero; // ������������� ������ ������� ������ ���� digits = nullptr; // ������������� ��������� �� ������ � nullptr exponent = MinEtype; // ����������� ���������� ���������� ��������� ����� #ifdef Debug_voice // ������ ������ ���������� ����������. ��������, ���� ��������� CDtor_voice cout << "Default Ctor\n"; // ���������� ���������� #endif // Debug_voice } // Default Ctor LongReal::LongReal(const string& value) { /** ����������� � �������������� ����� �� ������ **/ string::const_iterator cit = value.cbegin(); // ������������� �������� � ������ ������ if((value.length()==sOne)&&(*cit==chZero)) { // ���� ������ ������� �� ������ �������� � ���� ������� ����� ����, sign = false; // ������������� ��������� ������ � "����" NumCount = sZero; // ������������� ������ ������� ������ ���� digits = nullptr; // ������������� ��������� �� ������ � nullptr exponent = MinEtype; // ����������� ���������� ���������� ��������� ����� return; // � ������� }; // ���� �� ������ �� ������� �� ������ �������� ��� ���� ������� �� ����� ����, �� string temp = Corrector(value); // �������� ����������������� ������ �� ��������������� ���������� if((temp.length()==sOne)&&(*temp.begin()==chPoint)) { // ���� ������ ������ ����� ������ �������, � ���� ������ ����� ����� sign = false; // ������������� ��������� ������ � "����" NumCount = sZero; // ������������� ������ ������� ������ ���� digits = nullptr; // ������������� ��������� �� ������ � nullptr exponent = MinEtype; // ����������� ���������� ���������� ��������� ����� } else { // ����� digits = nullptr; // ������������� ��������� �� ������ � nullptr LongReal::init(temp); // � �������������� ������ ������� }; #ifdef Debug_voice // ������ ������ ���������� ����������. ��������, ���� ��������� CDtor_voice cout << "Ctor with string parametrs\n"; #endif // Debug_voice } // Ctor with string parametrs LongReal::LongReal(const double& value) { /** ����������� � �������������� ����� �� ����� ���� double **/ if(value == dZero) { // ���� value ����� ����, �� digits = nullptr; // ������������� ��������� �� nullptr LongReal::setzero(); // ���������� ���� � return; // �� ���� ������ ������������ ��������� }; if(value == numeric_limits<double>::infinity()) { // ���� value ����� �������������, �� digits = nullptr; // ������������� ��������� �� nullptr LongReal::setposinf(); // ���������� ������������� ������������� return; // �� ���� ������ ������������ ��������� }; if(value == -numeric_limits<double>::infinity()) { // ���� value ����� ����� �������������, �� digits = nullptr; // ������������� ��������� �� nullptr LongReal::setneginf(); // ���������� ������������� ������������� return; // �� ���� ������ ������������ ��������� }; if(isnan(value)) { // ���� value ����� NaN, �� digits = nullptr; // ������������� ��������� �� nullptr LongReal::setNaN(); // ���������� NaN return; // �� ���� ������ ������������ ��������� }; stringstream ss; // ������� ����� ��� �������� �� ������� ss << fixed << setprecision(mant) << value; // ���������� � ����� value ������������������� �������� � �������� ������ �������� digits = nullptr; // ������������� ��������� �� ������ � nullptr LongReal::init(Corrector(ss.str())); // �������������� ������ ������� �� ������ #ifdef Debug_voice // ������ ������ ���������� ����������. ��������, ���� ��������� CDtor_voice cout << "Ctor with double parametrs\n"; #endif // Debug_voice } // Ctor with double parametrs LongReal::LongReal(const LongReal& obj ) { /** ����������� ����������� **/ NumCount = obj.NumCount; // �������� ����� ������� sign = obj.sign; // �������� ���� ����� exponent = obj.exponent; // �������� ���������� if(obj.digits) { // ���� ������ � ������� ����������, �� digits = new(nothrow) Dtype[NumCount]; // �������� ������ ������ ������� if(!digits) { // ���� ������ �������� �� �������, �� setzero(); // ������������� ���� ����� � ���� return; // �� ���� ������ ������������ ��������� }; // ���� �� ������ ��������, �� memcpy(digits, obj.digits, sizeof(Dtype)*NumCount); // �������� ������� return; // �� ���� ������ ������������ ��������� }; digits = nullptr; // ���� ������ � ������� �� ����������, �� ������������� ��������� ������� � nullptr #ifdef Debug_voice // ������ ������ ���������� ����������. ��������, ���� ��������� CDtor_voice cout << "Copy Ctor\n"; #endif // Debug_voice } // Copy Ctor LongReal::LongReal(LongReal&& obj) { /** ����������� ����������� **/ digits = nullptr; setzero(); // ���������� ���� � ������� ����� swap(obj); // ������������ � �������� ����������� #ifdef Debug_voice // ������ ������ ���������� ����������. ��������, ���� ��������� CDtor_voice cout << "Move Ctor\n"; #endif // Debug_voice } // Move Ctor LongReal::LongReal(Stype _sign, size_t _NumCount, Dtype* &_digits, Etype _exp) { /** ����������� ������� �������� ����� �� ��������� ������������. ����� ���� ������� ��� �������� ��������. **/ sign = _sign; // ���� ������� ������������� ������ NumCount = _NumCount; // ������������� ������ ������� ������ ���� digits = _digits; // ������������� ��������� �� ������ _digits _digits = nullptr; // ������������� ��������� �� nullptr exponent = _exp; // ����������� ���������� ���������� ��������� ����� #ifdef Debug_voice // ������ ������ ���������� ����������. ��������, ���� ��������� CDtor_voice cout << "Direct Ctor\n"; // ���������� ���������� #endif // Debug_voice } // Direct Ctor LongReal::~LongReal() { /** ���������� **/ if(digits) delete[] digits; // ���� ������ ����������, �� ������� ��� #ifdef Debug_voice // ������ ������ ���������� ����������. ��������, ���� ��������� CDtor_voice cout << "Dtor" << endl; #endif // Debug_voice } // Dtor LongReal& LongReal::operator=(const LongReal &obj) { /** ���������� ��������� ������������ ������������ ������������ �������. ����������� � ������ �����������-�-������ (copy-and-swap idiom) **/ LongReal tmp(obj); // �������� ����������� ����������� � �������� ����� obj � ���������� tmp swap(tmp); // ������������ ����������� � tmp #ifdef Debug_voice // ������ ������ ���������� ����������. ��������, ���� ��������� CDtor_voice cout << "Copy operator=LongReal &obj\n"; #endif // Debug_voice return *this; } // Copy operator= LongReal& LongReal::operator=(const double &value) { /** ���������� ��������� ������������ ������������ ���������� ���� double. ����������� � ������ �����������-�-������ (copy-and-swap idiom) **/ LongReal tmp(value); // �������� ����������� � �������������� ����� �� ����� ���� double swap(tmp); // ������������ ����������� � tmp #ifdef Debug_voice // ������ ������ ���������� ����������. ��������, ���� ��������� CDtor_voice cout << "Copy operator= double &value\n"; #endif // Debug_voice return *this; } // Copy operator= from double LongReal& LongReal::operator=(const string &value) { /** ���������� ��������� ������������ ������������ ���������� ���� string. ����������� � ������ �����������-�-������ (copy-and-swap idiom) **/ LongReal tmp(value); // �������� ����������� � �������������� ����� �� ������ swap(tmp); // ������������ ����������� � tmp #ifdef Debug_voice // ������ ������ ���������� ����������. ��������, ���� ��������� CDtor_voice cout << "Copy operator=string &value\n"; #endif // Debug_voice return *this; } // Copy operator= from string LongReal& LongReal::operator=(LongReal &&obj) { /** ���������� ��������� ������������ ������������ ������������ ������� **/ // if(digits) delete[] digits; // ���� ������ ����������, �� ������� ��� setzero(); // �������� ��� ��������� swap(obj); // ������������ � �������� ����������� #ifdef Debug_voice // ������ ������ ���������� ����������. ��������, ���� ��������� CDtor_voice cout << "Move operator=obj\n"; #endif // Debug_voice return *this; } // Move operator= void LongReal::swap(LongReal& obj) noexcept { /** ������� ������ ���������� ����� ���������. ������� ��������� noexcept - �� ���������� ���������� **/ std::swap(NumCount, obj.NumCount); // ���������� �������� std::swap(sign, obj.sign); // ���������� �������� std::swap(exponent, obj.exponent); // ���������� �������� std::swap(digits, obj.digits); // ���������� ��������� } // LongReal::swap void LongReal::View(ostream& os) const { /** ����� ����������� �������� ����� **/ os << "sign= " << sign << endl; os << "NumCount= " << NumCount << endl; os << "exponent= " << exponent << endl; if(!digits) os << "digits = nullptr" << endl; else { os << "digits are: "; for(size_t i=0; i<NumCount; i++) os << *(digits+i); }; os << endl << endl; } // View void LongReal::ViewM(ostream& os) const { /** ����� ����������� �������� ����� � ������� ������� � ������� **/ os << "sign= " << sign << endl; os << "NumCount= " << NumCount << endl; os << "exponent= " << exponent << endl; if(!digits) os << "digits = nullptr" << endl; else { os << "digits are: \n"; for(size_t i=0; i<NumCount; i++) os << *(digits+i) << endl; }; os << endl << endl; } // ViewM size_t LongReal::Size() const { /** ����� ���������� ������ �������� ���������� � ������ **/ return (sizeof(size_t) + sizeof(Stype) + sizeof(Etype) + sizeof(Dtype)* NumCount); } // LongReal::Size template <typename T, class> /** ���������� ����� � ����� string, long double, double ��� float **/ T LongReal::Get() const { T tmp; LongReal::getstream() >> tmp; return tmp; } // T LongReal::Get /** �������� ���������� ������� ����������, ���� ����������� ��������� ������� � �� ���������� ��������� �� ������ ������: LongReal.h � LongReal.cpp. ���� ����������� � ���������� ��������� � ����� ����� LongReal.h, �� �������� ����������� ������� �� ���������. **/ /** ������ ������� ��� �� ���� �� �������� �����, �������� ��� �����-���� ������ ��������. ������� ��� �� ������������ �� ��������� �����, ����������� ������ ����������� ��������. ����� �������� �����-���� ���, ���������� ������� ��������� �������: ���������� ���������� ��������� �������, ����� ���������� ��� ������������� �������� ������� (��� ����� �� ������� ������) https://runebook.dev/ru/docs/cpp/language/function_template **/ template string LongReal::Get<std::string>() const; // ����� ����������� �������� ���������� �������� � �������� template long double LongReal::Get<long double>() const; // ���������� ������� ��� �������-�����, �� ������� ��� ���������. template double LongReal::Get<double>() const; template float LongReal::Get<float>() const; string LongReal::LongReal::Get(const size_t n) const { /** ������� ���������� ����� � ����� string � �������� ����������� n ������ ����� ����� **/ if(this->isNaN()) return strNaN; // ���� ������ ����� NaN, ������� NaN � ������� if(this->isposInf()) return strInf; // ���� ������ ����� inf, ������� inf � ������� if(this->isnegInf()) return strNInf; // ���� ������ ����� -inf, ������� -inf � ������� char c=sZero; // ��������������� ���������� bool ind = false; // ��������� ����������� ����������� ����� � ������� ����� (�����) string str=""; // ������, ������������ �������� LongReal tmp = this->_round(n); // ������� ��������������� ����� � ��������� ��� �� n-�������� stringstream sst = tmp.getstream(); // �������� ����� � ����������� ������. ����� �������� ������ � ������� while(sst.get(c) && (c!=chPoint) && !sst.eof()) // ��������� ����������� �� ������, ���� �� ��������� ����� ��� ����� ������ str += c; // ��������� ������� ��������� � ������ if(c==chPoint) ind = true; // ���� ��������� �����, �� �������� ��������� �� true if(ind) { // ���� ��������� true (� ���������� "�" ����� �����), �� if(n==0) return str; // ���� ������� ����� �� ����� (n=0), ����� � ��������� ������ str += c; // ����� ��������� ��� ����� � ������, for(size_t i=sZero; i<n; i++) { // � ����� �������� ��� n �������� �� ������ sst.get(c); // ��������� ������: if(sst.eof()) { // ���� ��������� ����� ������, �� if(i<n) str +=chZero; // ���������, ���� i<n, �� ��������� ���� else break; } else str += c; }; } else { // ���� ����� �� �������� ������� ����� (����� �� ���������), �� str += chPoint; // ��������� ����� � ������ for(size_t i=sZero; i<n; i++) str +=chZero; // � ��������� ���� ����� ����� }; string tail; // ��������������� ���������� ��� ������� ������ sst >> tail; // ����� ������� ������ � ������. ����� ����� � ������ ��� ������ ��� return str; // ����� � ��������� ������ } // LongReal::Get(...) string LongReal::EGet(size_t _n) const { /** ���������� ����� � ���� ������ string � ������� ����� .ddddEn (�������� �� ��������) **/ if(this->isNaN()) return strNaN; // ���� ������ ����� NaN, ������� NaN � ������� stringstream sst; if(sign) sst << chMinus; // ��������� ���� �����, ���� �������������, �� ������� � ����� ���� "�����" // ���� ������ � ����� ����������� � ����� ������� � ���� ����� �������, �� ��������� ���������� if(( !digits) && (NumCount==sZero)) { // ��������� ����� �� ���� � ������������� if(exponent==MinEtype) { // ��������� ��������� x ���� sst << strZero; // ������� ����� "����" � ����� � return sst.str(); // ���������� ������ }; if(exponent==MaxEtype) { // ��������� ��������� ����� ������������� sst << strInf; // ������� ������������ ������������� � ����� � return sst.str(); // ���������� ������ (���� �������������� ��� ������� � �����) }; }; // �������� �� ���� � ������������� sst << chPoint; // ������� � ����� ����� size_t n = _n > NumCount ? NumCount: _n; // �������� ������� ����� �� _n � NumCount for(size_t i=0; i<n; i++) // ������� n ������ ����� ����� sst << *(digits+i); sst << 'E' << exponent; // ������� ���������� return sst.str(); // ���������� ���������� ������ } // LongReal::EGet LongReal& LongReal::Expchange(const Etype _exch) { /** ����� ���������� ������, � �������� ���������� �������� �� �������� +_exch. ��� �������� ����� ������������ ������ ����� ���������������� ��������� �� ������������ enum Scale: NANO=-9, MICRO=-6, MILL=-3, KILO = 3, MEGA=6, GIGA=9. ����� ��������� ������������ � �������� �������� ������ ����� � ����� �������� ��� ����� ������ ������������, ������� ���������� ����������� � ���� ����� ���� long double, double ��� float, � ����� �������� ������������ ������� ��-�� ������� ������� �� �����. ���������� ������ �������� ����� ����� ��������� ������� � ����� �������� ���������� �� ������� �������. **/ if( (this->isNaN()) || (this->isZero()) || (this->isposInf()) || (this->isnegInf()) ) // ���� ������ NaN, +/-���� return *this; // ��� ����� �������������, ���������� ������ if(ovrflw(this->exponent, _exch)) return *this; // ��� ��������� ������������, ���������� ������ ��� ��������� this->exponent += _exch; // ������ ���������� ����� return *this; // ���������� ���������� ������ } // & LongReal::Expchange bool LongReal::isZero() const { /** ����� ���������� true, ���� ����� ����� ������ ���� (�������������� ��� ��������������): ���� ����� �� �����������. **/ if((!digits) && (NumCount==sZero) && (exponent == MinEtype)) return true; return false; } // LongReal::isZero bool LongReal::isposInf() const { /** ����� ���������� true, ���� ����� ����� Infinity (������������� �������������) **/ if((!sign) && (!digits) && (NumCount==sZero) && (exponent == MaxEtype)) return true; return false; } // LongReal::isposInf bool LongReal::isnegInf() const { /** ����� ���������� true, ���� ����� ����� -Infinity (������������� �������������) **/ if((sign) && (!digits) && (NumCount==sZero) && (exponent == MaxEtype)) return true; return false; } // LongReal::isnegInf bool LongReal::isNaN() const { /** ����� ���������� true, ���� ����� ������������ (����� NaN) **/ if( (digits) && (NumCount==sOne) && (exponent == eZero) && (*digits == dMask) ) return true; return false; } // LongReal::isNaN bool LongReal::operator==(const LongReal& x) const { /** �������� ���������� ��� ����� � ���������� true, ���� ����� �����. ���� ���� � ����� ���� ����� ���� �����. **/ if( this->isNaN() ) return false; // ���� ����� ������ ��������� NaN �� ������� �� ����� if( ( !digits) && ( NumCount==sZero) && ( exponent == MinEtype) &&\ (!x.digits) && (x.NumCount==sZero) && (x.exponent == MinEtype) ) return true; // ���� ��� ����� ����, �� true, �������� �� ���� if (sign ^ x.sign) // ���� ����� ������, �� False return false; if (exponent != x.exponent) // ���� ��������� ������, �� false return false; if (NumCount != x.NumCount) // ���� ���������� ���� ����� ������, �� false return false; for (size_t i = sZero; i < NumCount; i++) // ���������� ������ ����� if (*(digits+i) != *(x.digits+i)) // ���� ������� ����������� ���� �� � ����� �����, �� false return false; return true; } // LongReal::operator== bool LongReal::operator!=(const LongReal& x) const { return !(*this == x); } // LongReal::operator!= LongReal LongReal::operator*(const LongReal& x) const { /** �������� ��������������� ���������. ���������� ��������� ��������� ���� ����� ���� LongReal � ���� ������ ������� **/ LongReal res; // �������� ������ ��� ������ ����������. �� �������� ���� if( (this->isNaN()) || (x.isNaN()) ) { // �������� �� NaN. ���� ����� �� ���������� NaN, �� res.setNaN(); // ������������� ��������� � NaN return res; // � ������� }; res.sign = sign ^ x.sign; // ���������� � ����������� ���� ���������� if( (this->isZero() && !x.isposInf() && !x.isnegInf()) || // ���� ���� �� ������������ ����� ����, � ������ �� ����� (x.isZero() && !this->isposInf() && !this->isnegInf()) ) return res; // ����� �������������, �� ��������� ����� ���� if( (this->isZero() && (x.isposInf() || x.isnegInf())) || // ���� ���� �� ������������ ����� ����, � ������ (x.isZero() && (this->isposInf() || this->isnegInf()))) { // ����� ����� �������������, res.setNaN(); // �� ��������� ����� NaN return res; }; // ����� ����������� �������� ���� ����� ��� � ������ ��� ���� if(ovrflw(exponent, x.exponent) || // � ������ ������������ ��� ���� ����� �� �������� (x.exponent==MaxEtype) || (exponent==MaxEtype)) { // �����������, �� ��������� ����� ��������� if( (exponent < eZero) && (x.exponent < eZero) ) { // ���� ��� ���������� �������������, �� res.setzero(); // ������������ ����� ���� res.sign = x.sign ^ sign; // � ������ ����� return res; }; // ��� ������ ���������� ������ ���������: res.setposinf(); // ������������� � ��������� ������������� ������������� res.sign = x.sign ^ sign; // ���������� � ����������� ���� ����������, return res; // ������� � ���������� ��������� }; // ��������� �������� �� ������������ ���������� ��� ������������ res.NumCount = NumCount + x.NumCount; // ������������ ����� ������ ����� �� ������ ����� ���� ������������� ����� res.exponent = exponent + x.exponent; // ���������� ���������� res.digits = new(nothrow) Dtype[res.NumCount]; // �������� ������ ������ ������� if(!res.digits) { // ���� ������ �� ������, �� res.setNaN(); // ������������� NaN (���� NaN �� ����������, �� ��������������� inf) return res; // � ���������� ��������� }; for(size_t i=sZero; i<res.NumCount; i++) // ��������� ����� ���������� ������� (� ��������� ������ � *(res.digits+i) = dZero; // �������������� ��������� ������� ����� ��������� ��������� ����� for(size_t i = sZero; i<NumCount; i++) // �������� "� �������": for(size_t j=sZero; j<x.NumCount; j++) // ���������� ��������� ������������ ���� *(res.digits+i+j+sOne) += (*(digits+i)) * (*(x.digits+j)); // �� i-�� � j-�� �������� // � ���������� ������ ������������ � ������� ����� ���������� ���������� �����, ������� ����� ��������� ��������: const Dtype dTen = 10; for(size_t i=res.NumCount-1; i>sZero; i--) { *(res.digits+i-sOne) += *(res.digits+i)/dTen; // ��������� � ����� �������� ������� ������� �������� ������� *(res.digits+i) %= dTen; // ��������� ������ ������� � �������� ������� }; res.normalize(); // ����������� ����� res.Resize(manDigits); // �������� �������� �� ���������� �������� return res; // ���������� ��������� } // LongReal::operator* LongReal LongReal::operator-() const { /** �������� ������� �����. ���������� ������ �� ������ ����� **/ LongReal res(*this); // ������� ����� ������ ������������ res.sign = !sign; // ������ ���� ����� return res; // ���������� ������ } // LongReal operator-() bool LongReal::operator>(const LongReal& x) const { /** �������� ��������� "������" **/ if((this->isNaN()) || (x.isNaN())) return false; // ���� ����� �� ����� ������������, �� ��������� false if(this->isZero() && x.isZero()) return false; // ���� ��� ����� - +/-����, �� ������� if (sign ^ x.sign) return x.sign; // ������������� ����� ������ �������������� // ���� ����� � ����� ����������: if ((exponent != x.exponent) && (!this->isNaN()) && (!x.isNaN())) // ���� ���������� ������ � ����� �� NaN, return (exponent > x.exponent) ^ sign; // �� ������ ����� � ������� ����������� � ������ ����� // ���� ���������� � ����� ����������: if((this->isZero()) && (!x.isZero())) return sign; // ���� ������ - ���� ����, � ������ �� ����, �� ������ ������ ������� if((!this->isZero()) && (x.isZero())) return !sign; // ���� ������ ����� - �� ����, � ������ ���� ���� - �� ������ ������ if(( this->isposInf()) && (!x.isposInf())) return true; // ������ +�������������, ������ �� +������������� - ����� if((!this->isposInf()) && ( x.isposInf())) return false; // ������ �� +�������������, ������ +������������� - ���� if(( this->isnegInf()) && (!x.isnegInf())) return false; // ������ -�������������, ������ - ����� - ���� if((!this->isnegInf()) && ( x.isnegInf())) return true; // ������ �� -�������������, ������ -������������� - ����� size_t NMAX = max(this->NumCount, x.NumCount); // ���������� ������������ ����� � ���� �������� LongReal DD1(*this); // ������ ����� �������� ����� LongReal DD2(x); // ������ ����� ������� ����� DD1.incrD(NMAX); // ����������� ����� �������� � ����� �������� DD2.incrD(NMAX); // �� �������� NMAX if(DD1.NumCount != DD2.NumCount) return false; // ���� ��������� ����� �������� �� �������, �� ������� � false for(size_t i=sZero; i<NMAX; i++) // ���������� ��������������� ����� ���� �������� ����� �����: if( *(DD1.digits+i) != *(DD2.digits+i) ) // �� ������� �������� � �������. ���� ��� �� �����, ��: return ( *(DD1.digits+i) > *(DD2.digits+i) ) ^ sign; // ������� �� ����� � ���������� ��������� ��������� � ������ ����� return false; // ���������� false, ���� ��� ����� ������� D1 ������ ��������������� ���� ������� D2 } // LongReal::operator> bool LongReal::operator<(const LongReal& x) const { /** �������� ��������� "������" **/ if((this->isNaN()) || (x.isNaN())) return false; // ���� ����� �� ����� ������������, �� ������� return !(*this > x || *this == x); } // LongReal::operator< bool LongReal::operator>=(const LongReal& x) const { /** �������� ��������� "������ ��� �����" **/ if((this->isNaN()) || (x.isNaN())) return false; // ���� ����� �� ����� ������������, �� ������� return *this > x || *this == x; } // LongReal::operator>= bool LongReal::operator<=(const LongReal& x) const { /** �������� ��������� "������ ��� �����" **/ if((this->isNaN()) || (x.isNaN())) return false; // ���� ����� �� ����� ������������, �� ������� return *this < x || *this == x; } // LongReal::operator<= LongReal LongReal::operator+(const LongReal& x) const { /** �������� ��������������� ��������. ���������� ��������� �������� ���� ����� ���� LongReal **/ if(this->isZero()) return x; // ���� �� ����� ����, �� ���������� x if(x.isZero()) return *this; // ���� x ����� ����, �� ���������� ���� LongReal E1; // ������� ������ E1.setNaN(); // ������������� � ���� ������� NaN if(this->isNaN() || x.isNaN() || // ���� ����� �� ��������� NaN, ��������� NaN (this->isposInf() && x.isnegInf()) || // �������� ��������������� �������������� (x.isposInf() && this->isnegInf())) return E1; // ���� ���� ���������������� NaN E1.setposinf(); // ����������� "���� �������������" LongReal E2; // ������� ������ � E2.setneginf(); // ����������� ��� "����� �������������" if(((this->isposInf()) && (!x.isnegInf())) || ((x.isposInf()) && (!this->isnegInf()))) return E1; // �������� ����� � �������������� if(((this->isnegInf()) && (!x.isposInf())) || ((x.isnegInf()) && (!this->isposInf()))) return E2; // ���� ��� �� ������������� LongReal res; // ������� �������� ������ if(!(sign ^ x.sign)) { // ���� ����� ���������� Etype EMAX = max(this->exponent, x.exponent); // ������� ������������ ������� �� �������� ���� ����� if(ovrflw(EMAX, eOne)) { // ��������� ����������� ������������, ���� ��� ���� res.setNaN(); // ������������� ����� ������ � NaN return res; // ������� � ���������� NaN }; E1 = this->incrE(EMAX); // ���������� ����� ��������� ��������������� ���������� ��� ����� E2 = x.incrE(EMAX); // �������� � ����������� � ��� ������� if(E1.isNaN() || E2.isNaN()) { // ���� ��� ��������� ��������� ��������� ������, �� res.setNaN(); // ������������� ��������� � NaN return res; // � ������� }; size_t NMAX = max(E1.NumCount, E2.NumCount); // ������� ������������ ������ ������� �� ���� �������� E1.incrD(NMAX); // ����������� ����� ������� ������� E2.incrD(NMAX); // ����������� ����� ������� ������� if( (E1.NumCount != NMAX) || (E2.NumCount != NMAX) ) { // ���� ����� �������� ��������� �� �������, �� res.setNaN(); // ������������� ��������� � NaN return res; // � ������� }; res.sign = E1.sign; // ���� ��������� ����� ����� ����� ������ �� �����, �������� E1 res.NumCount = NMAX+sOne; // ����� ������� ��������� ����� ����� NMAX+1 res.exponent = EMAX + eOne; // ���������� ��������� ����� ����� EMAX + 1 res.digits = new Dtype[res.NumCount]; // �������� ������ ������ ������� if(!res.digits) { // ���� ������ �� ��������, �� res.setNaN(); // ������������� �������� ����� � NaN � return res; // ������� }; for(size_t i=sZero; i<res.NumCount; i++) // �������� ������ ������� ������� *(res.digits+i) = dZero; // �������� ���� for(size_t i=sZero; i<NMAX; i++) { // ���������� ������� �������� �������, *(res.digits+i+sOne) = *(E1.digits+i) + *(E2.digits+i); }; for(size_t i=NMAX; i>sZero; i--) { // ����������� �� ������������ ��������: *(res.digits+i-1) += *(res.digits+i)/10; // ���������� � ����� �������� ������� ������� �������� *(res.digits+i) %= 10; // ��������� � �������� ������� ������ ������� }; res.normalize(); // ����������� ����� ���������� ����� res.Resize(manDigits); // �������� �������� �� ���������� �������� return res; // ���������� ����� }; return *this - (-x); // ���� ����� ������������ ����� ������, �� �� ������� �������� ������ � �������� ������ } // LongReal::operator+ LongReal LongReal::operator-(const LongReal& x) const { /** �������� ��������������� ���������. ���������� ��������� ��������� ���� ����� ���� LongReal **/ if(x.isZero()) return *this; // ���� x ����� ����, �� ���������� ���� if(this->isZero()) return -x; // ���� �� ����� ����, �� ���������� -x LongReal E1; // ������� ������ � E1.setNaN(); // ������������� ��� � NaN if(this->isNaN() || x.isNaN() || // ���� ����� �� ���������� NaN, ��������� NaN (this->isposInf() && x.isposInf()) || // ��������� �������������� ������ ����� (x.isnegInf() && this->isnegInf()) ) return E1; // ���� ���� ���������������� NaN E1.setposinf(); // ����������� E1 "���� �������������" LongReal E2; // ������� ������ � E2.setneginf(); // ����������� ��� "����� �������������" if( ((this->isposInf()) && (!x.isposInf())) || ((x.isnegInf()) && (!this->isnegInf())) ) return E1; if( ((this->isnegInf()) && (!x.isnegInf())) || ((x.isposInf()) && (!this->isposInf())) ) return E2; LongReal res; // ������� �������� ������ if(!(sign ^ x.sign)) { // ���� ����� ���������� Etype EMAX = max(this->exponent, x.exponent); // ������� ������������ ������� �� �������� ���� ����� if(ovrflw(EMAX, eOne)) { // ��������� ����������� ������������, ���� ��� ���� res.setNaN(); // ������������� ����� ������ � NaN return res; // ������� � ���������� NaN }; E1 = this->incrE(EMAX); // ������� ��������������� ���������� ��� ����� E2 = x.incrE(EMAX); // �������� � ����������� � ��� ������� if(E1.isNaN() || E2.isNaN()) { // ���� ��� ��������� ��������� ��������� ������, �� res.setNaN(); // ������������� ��������� � NaN return res; // � ������� }; size_t NMAX = max(E1.NumCount, E2.NumCount); // ������� ������������ ������ ������� �� ���� �������� E1.incrD(NMAX); // ����������� ����� ������� ������� E2.incrD(NMAX); // ����������� ����� ������� ������� if( (E1.NumCount != NMAX) || (E2.NumCount != NMAX) ) { // ���� ����� �������� ��������� �� �������, �� res.setNaN(); // ������������� ��������� � NaN return res; // � ������� }; res.sign = E1.sign; // ���� ��������� ����� ����� ����� ������ �� �����, �������� E1 res.NumCount = NMAX+sOne; // ����� ������� ��������� ����� ����� NMAX+1 res.exponent = EMAX + 1; // ���������� ��������� ����� ����� EMAX + 1 res.digits = new Dtype[res.NumCount]; // �������� ������ ������ ������� if(!res.digits) { // ���� ������ �� ��������, �� res.setNaN(); // ������������� �������� ����� � NaN � return res; // ������� }; for(size_t i=sZero; i<res.NumCount; i++) // �������� ������ ������� ������� *(res.digits+i) = dZero; // ��������� ���� LongReal* Big = nullptr; // ��������������� ���������: Big - ���������� LongReal* Lit = nullptr; // Lit - ���������� if(fabs(E1)>fabs(E2)) { // ������� ������� �� ������ ����� Big = &E1; // Big ��������� �� ������� �� ������ ����� Lit = &E2; // Lit ��������� �� ������� �� ������ ����� } else { Big = &E2; Lit = &E1; res.sign = !res.sign; // ������ ���� ���������� } for(size_t i=sZero; i<NMAX; i++) { // �������� �������� ������� *(res.digits+i+sOne) = *(Big->digits+i) - *(Lit->digits+i); }; for(size_t i=NMAX; i>sZero; i--) { // ����������� �� ������������ ��������: if( *(res.digits+i)< dZero ) { // ���� ������� ������ ���� ������ ����, �� *(res.digits+i) += 10; // �������� � �����������, ��������� 10 � �������� (*(res.digits+i-1))--; // ��������� �� 1 ���������� ������ } }; res.normalize(); // ����������� ����� ���������� ����� res.Resize(manDigits); // �������� �������� �� ���������� �������� return res; // ���������� ����� }; return *this + (-x); // ���� ����� ���������� ����� ������, �� ���������� �����, ������� ���� � ������� } // LongReal::operator- LongReal& LongReal::operator-=(const LongReal& x) { /** �������� ���������� �� �������� x **/ LongReal tmp(*this); // ������� ����� �������� ������� tmp = *this - x; // ���������� ��������� swap(tmp); // ������������ ���������� � ������ return *this; // ���������� ������� ������ } // LongReal::operator-= LongReal& LongReal::operator+=(const LongReal& x) { /** �������� ���������� �� �������� x **/ LongReal tmp(*this); // ������� ����� �������� ������� tmp = *this + x; // ���������� �������� swap(tmp); // ������������ ���������� � ������ return *this; // ���������� ������� ������ } // LongReal::operator-= LongReal LongReal::inverse() const { /** ���������� ��������� ����� �������� (1/�)/ **/ LongReal res; // ������� ������ ��� ����������. ��� �������� ����� ����� ���� if(this->isposInf() || this->isnegInf()) { // ���� ������� ��������� ����� ����� �������������, �� res.sign = sign; // �������������� ���� ����� ����� ������ ���������� � return res; // � ���������� ������ }; if(this->isNaN()) { // ��������� �� NaN. ���� NaN, �� res.setNaN(); // ��������� ������������� � NaN return res; // � ���������� ������ }; if(this->isZero()) { // ���� ������� ��������� ����� ����, �� res.setposinf(); // �� ������������ ������� ������������� ���� ������������� � res.sign = sign; // �������������� ���� ����� ����� ������ ���������� return res; // � ���������� ������ }; LongReal x(*this); // ��������� �����, x.sign = false; // ������ ��� ������������� LongReal d("1"); // C������� ��, ��� ����� ������ �� x � ������������ ������� res.sign = sign; // ���� ���������� ������� �� ������ ����� res.exponent = eOne; // ������ � ��������� ���������� while (x < d) { // ���� ����� ������ �������, x.exponent++; // ����� ����������� ��� ���������� (�������� �� 10 ����������) res.exponent++; // � ������ ���������� ���������� }; while (d < x) // ������� ����� d ������� x, ����� ������� ��� �� 10, d.exponent++; // ����� �������� ����� 100...0 res.exponent -= d.exponent - eOne; // ���������� �������� ���������� ���� � ����� ����� size_t numbers = sZero; // ���������� ��� ����������� ���� ������� ����� Etype intPart = max(eZero, res.exponent); // ����� ���� ����� ����� size_t maxNumbers = manDigits + (size_t)intPart; // ������������ ����� ���� ������� Dtype* tmp = new Dtype[maxNumbers]; // �������� ������ ���������������� ������� if(!tmp) { // ���� ������ �� ��������, �� res.setNaN(); // ������������� ��������� � NaN return res; // � ������� }; for(size_t i=sZero; i<maxNumbers; i++) // �������� ������ ������� ������� *(tmp+i) = dZero; do { Dtype div = dZero; // �������� � ���� while (d >= x) { // �������, ������� ��� ����� ������� x �� d: div++; // ��������� ��� �������� � div d -= x; // ��������� d �� �������� x }; d.exponent++; // ����������� ������� � 10 ��� *(tmp+numbers) = div; // ���������� �������������� ����� � ������ ���� numbers++; // ����������� ����� ����������� ���� } while((!d.isZero()) &&(numbers < maxNumbers) ); // � ������ ��� ��� ���� d �� ������ ������ ���� � �� ��������� ����� res.NumCount=maxNumbers; res.digits=tmp; // ������������� ��������� �� ������ � ������� res.normalize(); // ����������� ����� res.Resize(manDigits); // �������� �������� �� ���������� �������� return res; } // LongReal::inverse() LongReal LongReal::operator/(const LongReal& x) const { /** ���������� ��������� ������� **/ LongReal res; // ������� ������ ��� ���������� if( ((this->isposInf() || this->isnegInf()) && (x.isposInf() || x.isnegInf())) ||\ (this->isZero() && x.isZero()) ) { // ���� ��� ����� ����� ������������� ��� ��� ����� ����, �� res.setNaN(); // ������������� ��������� � NaN return res; // � ������� }; if(*this == x) { // ���� ����� ����� ���� �����, �� res = 1; // ������������� ��������� � ������� return res; // � ���������� �� }; res = *this * x.inverse(); // ��������� ��������� �� �������� �������� x return res; } // LongReal::operator/ bool LongReal::StF(ofstream &_outF) const { /** ������ �������� ���������� ������ � �������� ���������� ���� ofstream. ���������: _outF - ��������� ������ ofstream ��� ������ ������ **/ #ifdef Debug_voice long bpos = _outF.tellp(); // ���������� ������� � ������ ����� cout << "LongReal::StF begin bpos= " << bpos << endl; #endif // Debug_voice if(!SEF(_outF, NumCount)) return false; // ��������� ���������� ���� � ����� (����� ������� digits) if(!SEF(_outF, sign)) return false; // ��������� ���� ����� if(!SEF(_outF, exponent)) return false; // ��������� ���������� ����� if(NumCount != sZero) // ���� ���������� ���� �� ����� ���� (�������� ������), �� if(!SEF(_outF, digits, NumCount)) return false; // ��������� ������ ���� #ifdef Debug_voice long epos = _outF.tellp(); // ���������� ������� � ����� ����� cout << "LongReal::StF end epos= " << epos << endl; #endif // Debug_voice return true; } // LongReal::StF bool LongReal::SaveToFile(const string _filename) const { /** ����� ������ �������� ���������� ������ � ���� **/ if(_filename == EmpStr) return false; // ���� ��� ����� ������, �� ����� � ������� false ofstream outF(_filename, ios::out | ios::binary); // ��������� ��� ����� � �������� ������� ��� ������ �� ���� if (!outF.is_open()) { // ���� ���� �� ������, �� ��������� ������������ � cout << "������ �������� �����" <<endl; // ������� false � ����� �� ������� return false; }; if(!StF(outF)) { // ���������� ������ � ����. ���� ���� �� �������, �� outF.close(); // �������� ���� � return false; // ������� � false }; outF.close(); // ��������� ���� return true; // ���������� true } // LongReal::SaveToFile bool LongReal::RfF(ifstream &_inF) { /** ������ �� �������� ���������� ���� ifstream � ������� ��������� ������. ���������: _inF - ��������� ������ ifstream ��� ������ ������ **/ #ifdef Debug_voice long bpos = _inF.tellg(); // ���������� ������� � ������ ����� cout << "LongReal::RfF begin bpos= " << bpos << endl; #endif // Debug_voice LongReal tmp; // ������� ��������������� ����������, ����� ������ � ��� if(!DSF(_inF, tmp.NumCount)) return false; // ������ ���������� ���� � ����� (����� ������� digits) if(!DSF(_inF, tmp.sign)) return false; // ������ ���� ����� if(!DSF(_inF, tmp.exponent)) return false; // ������ ���������� ����� if(tmp.NumCount !=sZero) { // ���� ���������� ���� �� ����� ���� (�������� ������), �� tmp.digits = new(nothrow) Dtype[tmp.NumCount]; // �������� ������ ������ ������� if(!tmp.digits) return false; // ���� ������ �� ��������, �� ����� � false if(!DSF(_inF, tmp.digits, tmp.NumCount)) return false; // ������ ������ ���� } else { tmp.digits = nullptr; // ����� ������������� ��������� ������� � nullptr #ifdef Debug_voice long epos = _inF.tellg(); // ���������� ������� � ����� ����� cout << "LongReal::RfF end epos= " << epos << endl; #endif // Debug_voice }; #ifdef Debug_voice long epos = _inF.tellg(); // ���������� ������� � ����� ����� cout << "LongReal::RfF end epos= " << epos << endl; #endif // Debug_voice swap(tmp); // ������������ ������� � ������� ����������� return true; // � ������� � true } // LongReal::RfF bool LongReal::ReadFromFile(const string _filename) { /** ����� ������ �� ����� � ������ � ������� ��������� ������ **/ if(_filename == EmpStr) return false; // ���� ��� ����� ������, �� ����� � ������� false ifstream inF(_filename, ios::in | ios::binary); // ��������� ��� ����� � �������� ������� ��� ������ � ����� if (!inF.is_open()) { // ���� ���� �� ������, �� ��������� ������������ � cout << "������ �������� �����" <<endl; // ������� false � ����� �� ������� return false; }; if(!RfF(inF)) { // ��������� ������ �� �����. ���� ���� �� �������, �� inF.close(); // ��������� ���� return false; // ����� � ������� false }; inF.close(); // ��������� ���� return true; // ���������� true } // ReadFromFile /********************************** ������������ ������ LongReal ������ *************************************************/ bool SEF(ofstream &_outF, LongReal& x) { /** ���������� ������ SEF ��� ���� LongReal **/ if(!x.StF(_outF)) return false; else return true; } // SEF bool SEF(ofstream &_outF, LongReal x[], size_t Cnt) { /** ���������� ������ SEF ��� ���� LongReal **/ bool flag; // ���� ������������� �������. ���� ��������� �� ������ �� ����� nullptr if(x && Cnt>nmSrlz::sZero) flag = true; else flag = false; // � ����� ������� ������ ����, ���� true. ����� false _outF.write((char*)&flag, sizeof(bool)); // ���������� ���� � ����� if(_outF.bad()) return false; // �������� ��������� ����� ������ badbit (https://cplusplus.com/reference/ios/ios/rdstate/) if(flag) // ���� ���� true, �� ���������� ������ � ����� for(size_t j{}; j<Cnt; j++) { if(!(x+j)->StF(_outF)) return false; }; return true; } // SEF bool DSF(ifstream &_inF, LongReal& x) { /** ���������� ������ DSF ��� ���� LongReal **/ if(!x.RfF(_inF)) return false; else return true; } // DSF bool DSF(ifstream &_inF, LongReal x[], size_t Cnt) { /** ���������� ������ DSF ��� ���� LongReal **/ bool flag; // ���� ������������� ������� _inF.read((char*)&flag, sizeof(bool)); // ������ ���� �� ����� if(_inF.bad()) return false; if(flag) { for(size_t i{}; i<Cnt; i++) if(!(x+i)->RfF(_inF)) return false; } else x = nullptr; return true; } // DSF ostream& operator<<(ostream& os, const LongReal& value) { /** ���������� ��������� ������ ����� � ����� ostream � ������������� ������������ � double. **/ double tmp; // ��������������� ���������� value.getstream() >> tmp; // ������������ ����� � double os << tmp; // ������� double � ����� return os; } // operator<< stringstream& operator>>(stringstream& ss, LongReal& value) { /** ���������� ��������� ����� ���������� �� ������ stringstream **/ LongReal tmp(ss.str()); value.swap(tmp); return ss; } // operator>> istream& operator>>(istream& is, LongReal& value) { /** ���������� ��������� ����� ���������� �� ������ istream **/ string buff; // ��������������� ���������� is >> buff; // ������ � ��������� � buff LongReal tmp(buff); // ������� ��������� ������ LongReal value.swap(tmp); // ������������ ����������� � value return is; // ���������� ������ �� ����� } // operator>> LongReal fabs(const LongReal& x) { /** ���������� ������ ����� x **/ LongReal res(x); // �������� ����� res.sign = false; // ������ ���� ����� �� "����" return res; } // LongReal::fabs /*************************************************************************************************************************/ /** **/ /** class lrstream **/ /** **/ /*************************************************************************************************************************/ /*********************************************** struct lrstream begin ***************************************************/ lrstream::lrstream(const size_t w) : N(w){ /** ����������� **/ pos->precision(N); } lrstream& lrstream::operator<<(const LongReal& val) { /** �������� ������ � ����� lrstream ������������ ����� ���� LongReal **/ *pos << val.Get(N); return *this; } lrstream& lrstream::operator<<(const string& val) { /** �������� ������ � ����� lrstream ����� std::string **/ *pos << val; return *this; } template<typename T, class> lrstream& lrstream::operator<<(T val) { /** �������� ������ � ����� lrstream ������������ ������� ���������� ����� **/ *pos << val; return *this; } /** ������������� ������� **/ template lrstream& lrstream::operator<<(const float val); template lrstream& lrstream::operator<<(const double val); template lrstream& lrstream::operator<<(const long double val); template lrstream& lrstream::operator<<(const char val); template lrstream& lrstream::operator<<(const char* val); template lrstream& lrstream::operator<<(char* val); template lrstream& lrstream::operator<<(size_t val); ostream& lrstream::operator<<(ostream&(*f)(ostream&)) { /** �������� ����� � ����� ������������ ��� ������ �� ������ lrstream � ����� ostream. � �������� ��������� ����� �������������� ������� lr_exit ��� ����������� ������������ std::endl, std::flush � ������ output-������������ �� ������������� ����� <ostream> (https://en.cppreference.com/w/cpp/io/manip.html) **/ return (*f)(*pos); // �������� ������� � ���������� �� �������� } /********************************************** struct lrstream end *******************************************************/ lrstream lr_precision(const size_t w) { /** ����������� ��� ����� ���� LongReal, float, double � long double. ������������� ���������� ��������� ������ ����� �������. **/ return lrstream(w); } lrstream operator <<(ostream& os, lrstream&& m) { /** �������� ����� ������� ���� lrstream � ����� ostream. ��������� ��������� ����� ostream ������� lrstream � ��������� � ����� lrstream ����������� ������. **/ m.pos = &os; m.pos->precision(m.N); return move(m); } lrstream operator <<(lrstream& los, lrstream&& m) { /** �������� ����� ������ ������� ���� lrstream � ����� lrstream. ��������� ��������� ������� ����� �� ������ ��������� ����� �������� ����� ������� � ����� ��������� ����� �������� **/ m.pos = los.pos; m.pos->precision(m.N); return move(m); } ostream& lr_exit(ostream& os) { return os; }; /** ����������� ��� ������ �� ������ lrstream � ����������� � ����� ostream. ������ ������������ lr_exit ����� �������������� ������������ std::endl, std::flush � ������ output-������������ �� ������������� ����� <ostream> (https://en.cppreference.com/w/cpp/io/manip.html)**/ #undef Debug_voice