#include "Rational.h" #include "Fraction/Fraction.h" #include #include #include #include using namespace std; Rational::Rational(){ num = 0; denum = 1; } Rational::Rational(int num1){ num = num1; denum = 1; } Rational::Rational(int num1, int num2) { num = num1; denum = num2; simple(); } Rational::Rational(float x) { const uint32_t bits = *(uint32_t*)(&x); const uint32_t signBit = bits >> 31; const uint32_t exponentBits = (bits >> 23) & 0xff; const uint32_t mantisBits = bits & 0x7fffff; uint32_t significand = (1u << 23u) | mantisBits; const int64_t sign = signBit ? -1 : 1; const int32_t exp = exponentBits - 127 - 23; static uint32_t smth = 1 << (uint32_t)(-exp); num = sign * (int64_t)(significand); denum = smth; cout << "float constructor work" << endl; simple(); } Rational::Rational(double x) { const unsigned long long int bits = *(unsigned long long int*)(&x); const unsigned long long int signBit = (bits >> 63) & 1; const unsigned long long int exponentBits = (bits >> 52) & 0x7ff; const unsigned long long int mantisBits = bits & 0xFFFFFFFFFFFFF; unsigned long long int significant = (long long int)pow(2, 52) | mantisBits; if (exponentBits == 0 and mantisBits == 0) { num = 0; denum = 1; } else if(exponentBits == 2046) { throw "Rational doesn't support NaN or Inf"; } const long long int sign = signBit ? -1 : 1; const long long int exp = exponentBits - 1023 - 52; num = (long long int)(sign * significant); denum = (long long int)pow(2, -exp); cout << "double constructor work" << endl; simple(); } Rational& Rational::operator += (const Rational& r) { Rational newrr = r; while (INT64_MAX - abs(num) < abs(r.num) or INT64_MAX - abs(denum) < abs(r.denum)) { if(abs(num) > 10000 or abs(denum) > 10000) { Fraction f(*this); f.layers.pop(); Rational newr(f); num = newr.num; denum = newr.denum; } if(abs(r.num > 10000) or abs(r.denum > 10000)) { Fraction f(r); f.layers.pop(); newrr = Rational(f); } } int scm = lcm(denum, newrr.denum); num = (num * (scm/denum) + newrr.num * (scm/newrr.denum)); denum = scm; return *this; } Rational Rational :: operator + (const Rational& r) const { Rational res(*this); return res += r; } Rational& Rational::operator -= (const Rational& r) { int scm = lcm(denum, r.denum); num = (num * (scm/denum) - r.num * (scm/r.denum)); denum = scm; return *this; } Rational Rational :: operator - (const Rational& r) const { Rational res(*this); return res -= r; } Rational& Rational::operator *= (const Rational& r) { cout << "suka *=" << endl; Rational newrr = r; while (INT64_MAX / abs(num) < abs(r.num) or INT64_MAX / abs(denum) < abs(r.denum)) { if(abs(num) > 10000 or abs(denum) > 10000) { Fraction f(*this); cout << "pop ne ok" << endl; f.show(); f.layers.pop(); cout << "pop ok" << endl; Rational newr = Rational(f); num = newr.num; denum = newr.denum; } if(abs(r.num) > 10000 or abs(r.denum) > 10000) { Fraction f(r); f.layers.pop(); newrr = Rational(f); } } num *= newrr.num; denum *= newrr.denum; simple(); return *this; } Rational Rational :: operator * (const Rational& r) const { cout << "suka *" << endl; Rational res(*this); return res *= r; } Rational& Rational::operator /= (const Rational& r) { num *= r.denum; denum *= r.num; simple(); return *this; } Rational Rational :: operator / (const Rational& r) const { Rational res(*this); return res /= r; } Rational Rational :: operator -() const { return Rational(-num, denum); } Rational& Rational :: operator += (const int r) { return (*this)+=Rational(r); } Rational Rational :: operator + (const int r) const { return (*this)+Rational(r); } Rational& Rational :: operator -= (const int r) { return (*this)-=Rational(r); } Rational Rational :: operator - (const int r) const { return (*this)-Rational(r); } Rational& Rational :: operator *= (const int r) { return (*this)*=Rational(r); } Rational Rational :: operator * (const int r) const { return (*this)*Rational(r); } Rational& Rational :: operator /= (const int r) { return (*this)/=Rational(r); } Rational Rational :: operator / (const int r) const { return (*this)/Rational(r); } ostream& operator <<(ostream& out, const Rational& r) { return out << '(' << r.num << ")/(" << r.denum << ')'; } Rational::operator double() const { return ((double)num/(double)denum); } Rational::operator int() const { return int(double(*this)); } long long int Rational::lcm(long long int num1, long long int num2) { int result = 1; for(int dnum = 2; num1 > 1 or num2 > 1; dnum++) { if(num1%dnum==0 or num2%dnum==0) { num1%dnum==0 ? num1/=dnum : num1*1; num2%dnum==0 ? num2/=dnum : num1*1; result *= dnum; dnum--; } } return result; } long long int Rational::gcd(long long int num1, long long int num2) { int s = 0; while (num1 && num2) { cout << num1 << ' ' << num2 << endl; if (abs(num1) >= abs(num2)) { cout << "num1 >= num2" << endl; num1 %= num2; } else { cout << "else" << endl; num2 %= num1; } s++; } return abs(num1 | num2); } void Rational::simple() { cout << "smth wrong in simple" << endl; long long int gct = gcd(num, denum); cout << "gcd: " << gct << endl; num /= gct; denum /= gct; cout << "simple work norm" << endl; } Rational Rational::sqrt() { cout << "sqrt work" << endl; Rational a = *this; Rational x = *this; for (long long int i = 0; i < 10000; i++) { x = (x + (a / x)) / 2; } cout << "sqrt work normal" << endl; return x; }