Advertisement
Guest User

Untitled

a guest
Apr 4th, 2013
14,573
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.00 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.   }
  83.  
  84.   return 0;
  85. }
  86.  
  87.  
  88. fraction::fraction (int _num, int _denum = 1)
  89. {
  90.   num = _num;
  91.   denum = _denum;
  92.  
  93.   isRadical = false;
  94.  
  95.   reduce();
  96. }
  97.  
  98. fraction::fraction (radical _num, int _denum = 1): numRadical(_num)
  99. {
  100.   denum = _denum;
  101.  
  102.   isRadical = true;
  103.  
  104.   reduce();
  105. }
  106.  
  107. std::string fraction::toString()
  108. {
  109.   std::stringstream ss;
  110.   if (denum == 0)
  111.     ss << "NaN. Shouldn't be here.";
  112.   else
  113.   {
  114.     if (!isRadical)
  115.       ss << num;
  116.     else
  117.       ss << numRadical.toString();
  118.  
  119.     if (denum > 1)
  120.       ss << '/' << denum;
  121.   }
  122.   return ss.str();
  123. }
  124.  
  125. void fraction::reduce()
  126. {
  127.   int a, b;
  128.   if (!isRadical)
  129.   {
  130.     a = abs(num);
  131.     b = abs(denum);
  132.   }
  133.   else
  134.   {
  135.     a = abs(numRadical.getPerfectSquare());
  136.     b = abs(denum);
  137.   }
  138.  
  139.   if (a < b)
  140.   {
  141.     a ^= b;
  142.     b ^= a;
  143.     a ^= b;
  144.   }
  145.   while (a*b != 0)
  146.   {
  147.     int tmp = b;
  148.     b = a%b;
  149.     a = tmp;
  150.   }
  151.  
  152.   int gcd = a + b;
  153.  
  154.   if (denum < 0)
  155.     gcd *= -1;
  156.  
  157.   if (!isRadical)
  158.     num /= gcd;
  159.   else
  160.     numRadical.radicand /= gcd*gcd;
  161.  
  162.   denum /= gcd;
  163. }
  164.  
  165. radical::radical(int _radicand)
  166. {
  167.   radicand = _radicand;
  168. }
  169.  
  170. std::string radical::toString()
  171. {
  172.   std::stringstream ss;
  173.   if (radicand < 0)
  174.   {
  175.     ss << "i*";
  176.     radicand *= -1;
  177.   }
  178.  
  179.   if (radicand == 0)
  180.     ss << 0;
  181.   else
  182.   {
  183.     int perfectSquare = getPerfectSquare();
  184.     if (perfectSquare != 1)
  185.       ss << perfectSquare;
  186.  
  187.     perfectSquare *= perfectSquare;
  188.     if (radicand != perfectSquare)
  189.       ss << ROOTSIGN << radicand/perfectSquare;
  190.   }
  191.   return ss.str();
  192. }
  193.  
  194. int radical::getPerfectSquare()
  195. {
  196.   int a = abs(radicand), square = 1;
  197.   int maxDiv = floor(sqrt(a));
  198.  
  199.   for (int i = 2; i <= maxDiv; i++)
  200.   {
  201.     while (a % (i*i) == 0)
  202.     {
  203.       a /= i*i;
  204.       square *= i;
  205.     }
  206.     maxDiv = floor(sqrt(a));
  207.   }
  208.  
  209.   return square;
  210. }
  211.  
  212. bool radical::isInteger()
  213. {
  214.   int s = getPerfectSquare();
  215.   return (radicand == s*s);
  216. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement