Rational.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #include "Rational.h"
  2. #include <iostream>
  3. #include <iomanip>
  4. #include <bitset>
  5. #include <math.h>
  6. using namespace std;
  7. Rational::Rational(){
  8. num = 0;
  9. denum = 1;
  10. }
  11. Rational::Rational(int num1, int num2)
  12. {
  13. num = num1;
  14. denum = num2;
  15. simple();
  16. }
  17. Rational::Rational(float x)
  18. {
  19. const uint32_t bits = *(uint32_t*)(&x);
  20. const uint32_t signBit = bits >> 31;
  21. const uint32_t exponentBits = (bits >> 23) & 0xff;
  22. const uint32_t mantisBits = bits & 0x7fffff;
  23. uint32_t significand = (1u << 23u) | mantisBits;
  24. const int64_t sign = signBit ? -1 : 1;
  25. const int32_t exp = exponentBits - 127 - 23;
  26. static uint32_t smth = 1 << (uint32_t)(-exp);
  27. num = sign * (int64_t)(significand);
  28. denum = smth;
  29. simple();
  30. }
  31. Rational::Rational(double x)
  32. {
  33. const unsigned long long int bits = *(unsigned long long int*)(&x);
  34. const unsigned long long int signBit = (bits >> 63) & 1;
  35. const unsigned long long int exponentBits = (bits >> 52) & 0x7ff;
  36. const unsigned long long int mantisBits = bits & 0xFFFFFFFFFFFFF;
  37. unsigned long long int significant = (long long int)pow(2, 52) | mantisBits;
  38. const long long int sign = signBit ? -1 : 1;
  39. const long long int exp = exponentBits - 1023 - 52;
  40. num = (long long int)(sign * significant);
  41. denum = (long long int)pow(2, -exp);
  42. simple();
  43. }
  44. Rational& Rational::operator += (const Rational& r)
  45. {
  46. int scm = lcm(denum, r.denum);
  47. num = (num * (scm/denum) + r.num * (scm/r.denum));
  48. denum = scm;
  49. return *this;
  50. }
  51. Rational Rational :: operator + (const Rational& r) const
  52. {
  53. Rational res(*this);
  54. return res += r;
  55. }
  56. Rational& Rational::operator -= (const Rational& r)
  57. {
  58. int scm = lcm(denum, r.denum);
  59. num = (num * (scm/denum) - r.num * (scm/r.denum));
  60. denum = scm;
  61. return *this;
  62. }
  63. Rational Rational :: operator - (const Rational& r) const
  64. {
  65. Rational res(*this);
  66. return res -= r;
  67. }
  68. Rational& Rational::operator *= (const Rational& r)
  69. {
  70. num *= r.num;
  71. denum *= r.denum;
  72. simple();
  73. return *this;
  74. }
  75. Rational Rational :: operator * (const Rational& r) const
  76. {
  77. Rational res(*this);
  78. return res *= r;
  79. }
  80. Rational& Rational::operator /= (const Rational& r)
  81. {
  82. num *= r.denum;
  83. denum *= r.num;
  84. simple();
  85. return *this;
  86. }
  87. Rational Rational :: operator / (const Rational& r) const
  88. {
  89. Rational res(*this);
  90. return res /= r;
  91. }
  92. ostream& operator <<(ostream& out, const Rational& r)
  93. {
  94. return out << '(' << r.num << ")/(" << r.denum << ')';
  95. }
  96. Rational::operator double() const
  97. {
  98. return ((double)num/(double)denum);
  99. }
  100. Rational::operator int() const
  101. {
  102. return int(double(*this));
  103. }
  104. long long int Rational::lcm(long long int num1, long long int num2)
  105. {
  106. int result = 1;
  107. for(int dnum = 2; num1 > 1 or num2 > 1; dnum++)
  108. {
  109. if(num1%dnum==0 or num2%dnum==0)
  110. {
  111. num1%dnum==0 ? num1/=dnum : num1*1;
  112. num2%dnum==0 ? num2/=dnum : num1*1;
  113. result *= dnum;
  114. dnum--;
  115. }
  116. }
  117. return result;
  118. }
  119. long long int Rational::gcd(long long int num1, long long int num2)
  120. {
  121. while (num1 && num2)
  122. if (num1 >= num2)
  123. num1 %= num2;
  124. else
  125. num2 %= num1;
  126. return num1 | num2;
  127. }
  128. void Rational::simple()
  129. {
  130. long long int gct = gcd(num, denum);
  131. num /= gct;
  132. denum /= gct;
  133. }