Advertisement
Guest User

Untitled

a guest
Apr 4th, 2013
1,051
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.08 KB | None | 0 0
  1. #include <iostream>
  2. #include <sstream>
  3. #include <cmath>
  4. #include <cstdlib>
  5.  
  6. #define ROOTSIGN ((char)0xAC + std::string("/"))
  7.  
  8. struct radical
  9. {
  10.   int radicand;
  11.  
  12.   radical(int _radicand = 0);
  13.   std::string toString();
  14.  
  15.   int getPerfectSquare();
  16.   bool isInteger();
  17. };
  18.  
  19. class fraction
  20. {
  21.   private:
  22.     int num;
  23.     radical numRadical;
  24.     int denum;
  25.  
  26.     bool isRadical;
  27.  
  28.     void reduce();
  29.  
  30.   public:
  31.     fraction (int _num, int _denum);
  32.     fraction (radical _num, int _denum);
  33.     std::string toString();
  34. };
  35.  
  36. int main()
  37. {
  38.   setlocale(LC_ALL, "russian");
  39.   int a, b, c;
  40.   std::cin >> a >> b >> c;
  41.  
  42.   if (a == 0)
  43.   {
  44.     if (b != 0)
  45.       std::cout << "a = 0; уравнение вырождается в линейное:\n"
  46.                 << "x = " << fraction(-c,b).toString() << std::endl;
  47.     else if (c == 0)
  48.       std::cout << "Все коэффициенты равны нулю; x - любое число." << std::endl;
  49.     else
  50.       std::cout << "Нет решений." << std::endl;
  51.   }
  52.   else
  53.   {
  54.     long long discriminant = b*b - 4*a*c;
  55.  
  56.     if (discriminant > 0)
  57.     {
  58.       std::cout << "D > 0; 2 корня:\n";
  59.  
  60.       radical dRoot (discriminant);
  61.  
  62.       if (dRoot.isInteger())
  63.       {
  64.         std::cout << "x1 = " << fraction(-b + sqrt(discriminant), 2*a).toString() << "\n"
  65.                   << "x2 = " << fraction(-b - sqrt(discriminant), 2*a).toString() << std::endl;
  66.       }
  67.       else
  68.       {
  69.         std::string rational = fraction(-b, 2*a).toString(),
  70.                     irrational = fraction(radical(discriminant), 2*a).toString();
  71.         if (rational == "0")
  72.           std::cout << "x1 = " << irrational << "\n"
  73.                     << "x2 = " << "- " << irrational << std::endl;
  74.         else
  75.           std::cout << "x1 = " << rational << " + " << irrational << "\n"
  76.                     << "x2 = " << rational << " - " << irrational << std::endl;
  77.       }
  78.     }
  79.     else if (discriminant == 0)
  80.       std::cout << "D = 0; 1 корень:\n"
  81.                 << "x = " << fraction(-b, 2*a).toString() << std::endl;
  82.     else if (discriminant < 0)
  83.       std::cout << "D < 0; нет корней." << std::endl;
  84.   }
  85.  
  86.   return 0;
  87. }
  88.  
  89.  
  90. fraction::fraction (int _num, int _denum = 1)
  91. {
  92.   num = _num;
  93.   denum = _denum;
  94.  
  95.   isRadical = false;
  96.  
  97.   reduce();
  98. }
  99.  
  100. fraction::fraction (radical _num, int _denum = 1): numRadical(_num)
  101. {
  102.   denum = _denum;
  103.  
  104.   isRadical = true;
  105.  
  106.   reduce();
  107. }
  108.  
  109. std::string fraction::toString()
  110. {
  111.   std::stringstream ss;
  112.   if (denum == 0)
  113.     ss << "NaN. Shouldn't be here.";
  114.   else
  115.   {
  116.     if (!isRadical)
  117.       ss << num;
  118.     else
  119.       ss << numRadical.toString();
  120.  
  121.     if (denum > 1)
  122.       ss << '/' << denum;
  123.   }
  124.   return ss.str();
  125. }
  126.  
  127. void fraction::reduce()
  128. {
  129.   int a, b;
  130.   if (!isRadical)
  131.   {
  132.     a = abs(num);
  133.     b = abs(denum);
  134.   }
  135.   else
  136.   {
  137.     a = abs(numRadical.getPerfectSquare());
  138.     b = abs(denum);
  139.   }
  140.  
  141.   if (a < b)
  142.   {
  143.     a ^= b;
  144.     b ^= a;
  145.     a ^= b;
  146.   }
  147.   while (a*b != 0)
  148.   {
  149.     int tmp = b;
  150.     b = a%b;
  151.     a = tmp;
  152.   }
  153.  
  154.   int gcd = a + b;
  155.  
  156.   if (denum < 0)
  157.     gcd *= -1;
  158.  
  159.   if (!isRadical)
  160.     num /= gcd;
  161.   else
  162.     numRadical.radicand /= gcd*gcd;
  163.  
  164.   denum /= gcd;
  165. }
  166.  
  167. radical::radical(int _radicand)
  168. {
  169.   radicand = _radicand;
  170. }
  171.  
  172. std::string radical::toString()
  173. {
  174.   std::stringstream ss;
  175.   if (radicand < 0)
  176.     ss << "NaN. Shouldn't get here.";
  177.   else if (radicand == 0)
  178.     ss << 0;
  179.   else
  180.   {
  181.     int perfectSquare = getPerfectSquare();
  182.     if (perfectSquare != 1)
  183.       ss << perfectSquare;
  184.  
  185.     perfectSquare *= perfectSquare;
  186.     if (radicand != perfectSquare)
  187.       ss << ROOTSIGN << radicand/perfectSquare;
  188.   }
  189.   return ss.str();
  190. }
  191.  
  192. int radical::getPerfectSquare()
  193. {
  194.   int a = radicand, square = 1;
  195.   int maxDiv = floor(sqrt(a));
  196.  
  197.   for (int i = 2; i <= maxDiv; i++)
  198.   {
  199.     while (a % (i*i) == 0)
  200.     {
  201.       a /= i*i;
  202.       square *= i;
  203.     }
  204.     maxDiv = floor(sqrt(a));
  205.   }
  206.  
  207.   return square;
  208. }
  209.  
  210. bool radical::isInteger()
  211. {
  212.   int s = getPerfectSquare();
  213.   return (radicand == s*s);
  214. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement