123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- #include "Rational.h"
- #include "Fraction/Fraction.h"
- #include <iostream>
- #include <iomanip>
- #include <bitset>
- #include <math.h>
- 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;
- }
|