Rational.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  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. cout << sign * (int64_t)(significand) << '/' << smth;
  28. num = sign * (int64_t)(significand);
  29. denum = smth;
  30. simple();
  31. }
  32. Rational::Rational(double x)
  33. {
  34. const unsigned long long int bits = *(unsigned long long int*)(&x);
  35. const unsigned long long int signBit = (bits >> 63) & 1;
  36. const unsigned long long int exponentBits = (bits >> 52) & 0x7ff;
  37. const unsigned long long int mantisBits = bits & 0xFFFFFFFFFFFFF;
  38. unsigned long long int significant = (long long int)pow(2, 52) | mantisBits;
  39. const long long int sign = signBit ? -1 : 1;
  40. const long long int exp = exponentBits - 1023 - 52;
  41. cout << bitset<64>(bits) << endl;
  42. cout << bitset<64>(signBit) << endl;
  43. cout << bitset<64>(exponentBits) << endl;
  44. cout << bitset<64>(mantisBits) << endl;
  45. cout << bitset<64>(pow(2,52)) << endl;
  46. cout << bitset<64>(significant) << endl;
  47. cout << bitset<64>(exp) << endl;
  48. cout << setprecision(15) << fixed << sign * significant << '/' << (unsigned long long int)pow(2, -exp) << endl;
  49. cout << (sign * significant) / pow(2, -exp) << endl;
  50. cout << sign * pow(2, -1022) * significant << endl;
  51. }
  52. Rational& Rational::operator += (const Rational& r)
  53. {
  54. int scm = lcm(denum, r.denum);
  55. num = (num * (scm/denum) + r.num * (scm/r.denum));
  56. denum = scm;
  57. return *this;
  58. }
  59. Rational Rational :: operator + (const Rational& r) const
  60. {
  61. Rational res(*this);
  62. return res += r;
  63. }
  64. Rational& Rational::operator -= (const Rational& r)
  65. {
  66. int scm = lcm(denum, r.denum);
  67. num = (num * (scm/denum) - r.num * (scm/r.denum));
  68. denum = scm;
  69. return *this;
  70. }
  71. Rational Rational :: operator - (const Rational& r) const
  72. {
  73. Rational res(*this);
  74. return res -= r;
  75. }
  76. Rational& Rational::operator *= (const Rational& r)
  77. {
  78. num *= r.num;
  79. denum *= r.denum;
  80. simple();
  81. return *this;
  82. }
  83. Rational Rational :: operator * (const Rational& r) const
  84. {
  85. Rational res(*this);
  86. return res *= r;
  87. }
  88. Rational& Rational::operator /= (const Rational& r)
  89. {
  90. num *= r.denum;
  91. denum *= r.num;
  92. simple();
  93. return *this;
  94. }
  95. Rational Rational :: operator / (const Rational& r) const
  96. {
  97. Rational res(*this);
  98. return res /= r;
  99. }
  100. ostream& operator <<(ostream& out, const Rational& r)
  101. {
  102. return out << '(' << r.num << ")/(" << r.denum << ')';
  103. }
  104. Rational::operator double() const
  105. {
  106. return ((double)num/(double)denum);
  107. }
  108. Rational::operator int() const
  109. {
  110. return int(double(*this));
  111. }
  112. int Rational::lcm(long long int num1, long long int num2)
  113. {
  114. int result = 1;
  115. for(int dnum = 2; num1 > 1 or num2 > 1; dnum++)
  116. {
  117. if(num1%dnum==0 or num2%dnum==0)
  118. {
  119. num1%dnum==0 ? num1/=dnum : num1*1;
  120. num2%dnum==0 ? num2/=dnum : num1*1;
  121. result *= dnum;
  122. dnum--;
  123. }
  124. }
  125. return result;
  126. }
  127. int Rational::gcd(long long int num1, long long int num2)
  128. {
  129. while (num1 && num2)
  130. if (num1 >= num2)
  131. num1 %= num2;
  132. else
  133. num2 %= num1;
  134. return num1 | num2;
  135. }
  136. void Rational::simple()
  137. {
  138. int gct = gcd(num, denum);
  139. num /= gct;
  140. denum /= gct;
  141. }