Rational.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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. // First, obtain bitwise representation of the value
  20. const uint32_t bitwiseRepr = *reinterpret_cast<uint32_t*>(&x);
  21. // Extract sign, exponent and mantissa bits (as stored in memory) for convenience:
  22. const uint32_t signBit = bitwiseRepr >> 31u;
  23. const uint32_t expBits = (bitwiseRepr >> 23u) & 0xffu; // 8 bits set
  24. const uint32_t mntsBits = bitwiseRepr & 0x7fffffu; // 23 bits set
  25. // mask lowest 23 bits (mantissa)
  26. uint32_t significand = (1u << 23u) | mntsBits;
  27. const int64_t signFactor = signBit ? -1 : 1;
  28. const int32_t exp = expBits - 127 - 23;
  29. static uint32_t smth = 1u << static_cast<uint32_t>(-exp);
  30. if(exp < 0)
  31. {
  32. cout << signFactor * static_cast<int64_t>(significand) << '/' << smth;
  33. }
  34. else
  35. {
  36. cout << signFactor * static_cast<int64_t>(significand * smth) << '/' << 1;
  37. }
  38. num = signFactor * static_cast<int64_t>(significand);
  39. denum = smth;
  40. simple();
  41. }
  42. Rational& Rational::operator += (const Rational& r)
  43. {
  44. int scm = lcm(denum, r.denum);
  45. num = (num * (scm/denum) + r.num * (scm/r.denum));
  46. denum = scm;
  47. return *this;
  48. }
  49. Rational Rational :: operator + (const Rational& r) const
  50. {
  51. Rational res(*this);
  52. return res += r;
  53. }
  54. Rational& Rational::operator -= (const Rational& r)
  55. {
  56. int scm = lcm(denum, r.denum);
  57. num = (num * (scm/denum) - r.num * (scm/r.denum));
  58. denum = scm;
  59. return *this;
  60. }
  61. Rational Rational :: operator - (const Rational& r) const
  62. {
  63. Rational res(*this);
  64. return res -= r;
  65. }
  66. Rational& Rational::operator *= (const Rational& r)
  67. {
  68. num *= r.num;
  69. denum *= r.denum;
  70. simple();
  71. return *this;
  72. }
  73. Rational Rational :: operator * (const Rational& r) const
  74. {
  75. Rational res(*this);
  76. return res *= r;
  77. }
  78. Rational& Rational::operator /= (const Rational& r)
  79. {
  80. num *= r.denum;
  81. denum *= r.num;
  82. simple();
  83. return *this;
  84. }
  85. Rational Rational :: operator / (const Rational& r) const
  86. {
  87. Rational res(*this);
  88. return res /= r;
  89. }
  90. ostream& operator <<(ostream& out, const Rational& r)
  91. {
  92. return out << '(' << r.num << ")/(" << r.denum << ')';
  93. }
  94. Rational::operator double() const
  95. {
  96. return ((double)num/(double)denum);
  97. }
  98. Rational::operator int() const
  99. {
  100. return int(double(*this));
  101. }
  102. int Rational::lcm(long long int num1, long long int num2)
  103. {
  104. int result = 1;
  105. for(int dnum = 2; num1 > 1 or num2 > 1; dnum++)
  106. {
  107. if(num1%dnum==0 or num2%dnum==0)
  108. {
  109. num1%dnum==0 ? num1/=dnum : num1*1;
  110. num2%dnum==0 ? num2/=dnum : num1*1;
  111. result *= dnum;
  112. dnum--;
  113. }
  114. }
  115. return result;
  116. }
  117. int Rational::gcd(long long int num1, long long int num2)
  118. {
  119. while (num1 && num2)
  120. if (num1 >= num2)
  121. num1 %= num2;
  122. else
  123. num2 %= num1;
  124. return num1 | num2;
  125. }
  126. void Rational::simple()
  127. {
  128. int gct = gcd(num, denum);
  129. num /= gct;
  130. denum /= gct;
  131. }