123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- #include "Rational.h"
- #include <iostream>
- #include <iomanip>
- #include <bitset>
- #include <math.h>
- using namespace std;
- Rational::Rational(){
- num = 0;
- denum = 1;
- }
- Rational::Rational(int num1, int num2)
- {
- num = num1;
- denum = num2;
- simple();
- }
- Rational::Rational(float x)
- {
- // First, obtain bitwise representation of the value
- const uint32_t bitwiseRepr = *reinterpret_cast<uint32_t*>(&x);
- // Extract sign, exponent and mantissa bits (as stored in memory) for convenience:
- const uint32_t signBit = bitwiseRepr >> 31u;
- const uint32_t expBits = (bitwiseRepr >> 23u) & 0xffu; // 8 bits set
- const uint32_t mntsBits = bitwiseRepr & 0x7fffffu; // 23 bits set
- // mask lowest 23 bits (mantissa)
- uint32_t significand = (1u << 23u) | mntsBits;
- const int64_t signFactor = signBit ? -1 : 1;
- const int32_t exp = expBits - 127 - 23;
- static uint32_t smth = 1u << static_cast<uint32_t>(-exp);
- if(exp < 0)
- {
- cout << signFactor * static_cast<int64_t>(significand) << '/' << smth;
- }
- else
- {
- cout << signFactor * static_cast<int64_t>(significand * smth) << '/' << 1;
- }
- num = signFactor * static_cast<int64_t>(significand);
- denum = smth;
- simple();
- }
- 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)
- {
- 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)
- {
- num *= r.num;
- denum *= r.denum;
- simple();
- return *this;
- }
- Rational Rational :: operator * (const Rational& r) const
- {
- 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;
- }
- 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));
- }
- 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;
- }
- int Rational::gcd(long long int num1, long long int num2)
- {
- while (num1 && num2)
- if (num1 >= num2)
- num1 %= num2;
- else
- num2 %= num1;
- return num1 | num2;
- }
- void Rational::simple()
- {
- int gct = gcd(num, denum);
- num /= gct;
- denum /= gct;
- }
|