Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <sstream>
- #include <cmath>
- #include <cstdlib>
- #define ROOTSIGN ((char)0xAC + std::string("/"))
- struct radical
- {
- int radicand;
- radical(int _radicand = 0);
- std::string toString();
- int getPerfectSquare();
- bool isInteger();
- };
- class fraction
- {
- private:
- int num;
- radical numRadical;
- int denum;
- bool isRadical;
- void reduce();
- public:
- fraction (int _num, int _denum);
- fraction (radical _num, int _denum);
- std::string toString();
- };
- int main()
- {
- setlocale(LC_ALL, "russian");
- int a, b, c;
- std::cin >> a >> b >> c;
- if (a == 0)
- {
- if (b != 0)
- std::cout << "a = 0; уравнение вырождается в линейное:\n"
- << "x = " << fraction(-c,b).toString() << std::endl;
- else if (c == 0)
- std::cout << "Все коэффициенты равны нулю; x - любое число." << std::endl;
- else
- std::cout << "Нет решений." << std::endl;
- }
- else
- {
- long long discriminant = b*b - 4*a*c;
- if (discriminant > 0)
- {
- std::cout << "D > 0; 2 корня:\n";
- radical dRoot (discriminant);
- if (dRoot.isInteger())
- {
- std::cout << "x1 = " << fraction(-b + sqrt(discriminant), 2*a).toString() << "\n"
- << "x2 = " << fraction(-b - sqrt(discriminant), 2*a).toString() << std::endl;
- }
- else
- {
- std::string rational = fraction(-b, 2*a).toString(),
- irrational = fraction(radical(discriminant), 2*a).toString();
- if (rational == "0")
- std::cout << "x1 = " << irrational << "\n"
- << "x2 = " << "- " << irrational << std::endl;
- else
- std::cout << "x1 = " << rational << " + " << irrational << "\n"
- << "x2 = " << rational << " - " << irrational << std::endl;
- }
- }
- else if (discriminant == 0)
- std::cout << "D = 0; 1 корень:\n"
- << "x = " << fraction(-b, 2*a).toString() << std::endl;
- else if (discriminant < 0)
- std::cout << "D < 0; нет корней." << std::endl;
- }
- return 0;
- }
- fraction::fraction (int _num, int _denum = 1)
- {
- num = _num;
- denum = _denum;
- isRadical = false;
- reduce();
- }
- fraction::fraction (radical _num, int _denum = 1): numRadical(_num)
- {
- denum = _denum;
- isRadical = true;
- reduce();
- }
- std::string fraction::toString()
- {
- std::stringstream ss;
- if (denum == 0)
- ss << "NaN. Shouldn't be here.";
- else
- {
- if (!isRadical)
- ss << num;
- else
- ss << numRadical.toString();
- if (denum > 1)
- ss << '/' << denum;
- }
- return ss.str();
- }
- void fraction::reduce()
- {
- int a, b;
- if (!isRadical)
- {
- a = abs(num);
- b = abs(denum);
- }
- else
- {
- a = abs(numRadical.getPerfectSquare());
- b = abs(denum);
- }
- if (a < b)
- {
- a ^= b;
- b ^= a;
- a ^= b;
- }
- while (a*b != 0)
- {
- int tmp = b;
- b = a%b;
- a = tmp;
- }
- int gcd = a + b;
- if (denum < 0)
- gcd *= -1;
- if (!isRadical)
- num /= gcd;
- else
- numRadical.radicand /= gcd*gcd;
- denum /= gcd;
- }
- radical::radical(int _radicand)
- {
- radicand = _radicand;
- }
- std::string radical::toString()
- {
- std::stringstream ss;
- if (radicand < 0)
- ss << "NaN. Shouldn't get here.";
- else if (radicand == 0)
- ss << 0;
- else
- {
- int perfectSquare = getPerfectSquare();
- if (perfectSquare != 1)
- ss << perfectSquare;
- perfectSquare *= perfectSquare;
- if (radicand != perfectSquare)
- ss << ROOTSIGN << radicand/perfectSquare;
- }
- return ss.str();
- }
- int radical::getPerfectSquare()
- {
- int a = radicand, square = 1;
- int maxDiv = floor(sqrt(a));
- for (int i = 2; i <= maxDiv; i++)
- {
- while (a % (i*i) == 0)
- {
- a /= i*i;
- square *= i;
- }
- maxDiv = floor(sqrt(a));
- }
- return square;
- }
- bool radical::isInteger()
- {
- int s = getPerfectSquare();
- return (radicand == s*s);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement