Rational 有理数表示(运算符操作)

本文详细介绍了有理数类的实现及其各种基本操作,包括构造、转换、算术运算、比较和输入输出。重点阐述了如何通过类封装有理数的属性和行为,确保操作的正确性和高效性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Rational.h

#ifndef RATIONAL_H
#define RATIONAL_H
 
/** @file
 * @brief rational和其操作符函数的完整定义
 */
 
/** @mainpage 有理数表示
 * 合并所有的rantional的所有操作
 * 该程序可以用于满足所有的运算符操作
 * 源文件:@link Rational.h Rational.cpp @endlink
 * @date 2013-11-10
 * @author Alex Lin
 * @version 1.0
 */
 
#include <cassert>
#include <cstdlib>
#include <istream>
#include <ostream>
#include <sstream>
 
/**
 * @brief The Rational class
 * 有理数操作
 */
class Rational
{
public:
    Rational();
    Rational(int num);
    Rational(int num, int den);
    Rational(double r);
    Rational& operator = (Rational const& that);
 
    float as_float();
    double as_double();
    long double as_long_double();
    void assign(int num, int den);
    void reduce();
    friend Rational abs(Rational const & r);
    friend Rational operator-(Rational const& r);
    friend Rational operator+(Rational const& lhs, Rational const& rhs);
    friend Rational operator-(Rational const& lhs, Rational const& rhs);
    friend Rational operator*(Rational const& lhs, Rational const& rhs);
    friend Rational operator/(Rational const& lhs, Rational const& rhs);
    friend bool operator==(Rational const& a, Rational const& b);
    friend bool operator!=(Rational const& a, Rational const& b);
    friend bool operator<(Rational const& a, Rational const& b);
    friend bool operator<=(Rational const& a, Rational const& b);
    friend bool operator>(Rational const& a, Rational const& b);
    friend bool operator>=(Rational const& a, Rational const& b);
    friend std::istream& operator>>(std::istream& in, Rational& rat);
    friend std::ostream& operator<<(std::ostream& out, Rational const& rat);
 
public:
    static int gcd(int n, int m);
    static int GCD( int n, int m );
    static int LCM(int a, int b);
 
private:
    int numerator;      //< 分子
    int denominator;    //< 分母
};
 
#endif // RATIONAL_H

Rational.cpp

#include "Rational.h"
 
///使用欧几里德算法计算最大公约数
int Rational::gcd(int n, int m)
{
    n = std::abs(n);
    while ( m != 0){
        int tmp(n%m);
        n = m;
        m = tmp;
    }
    return n;
}
 
///利用递归计算最大公约数
int Rational::GCD( int n, int m )
{
    if ( n % m == 0 )
        return m;
    else
        return GCD(m, n % m);
}
 
///求两个数的最小公倍数
int Rational::LCM(int a, int b)
{
    int temp_lcm;
    temp_lcm = a*b/GCD(a, b);//最小公倍数等于两数之积除以最大公约数
    return temp_lcm;
}
 
Rational::Rational()
    : numerator(0), denominator(1)
{/*空*/}
 
Rational::Rational(int num)
    : numerator(num), denominator(1)
{/*空*/}
 
Rational::Rational(int num, int den)
    : numerator(num), denominator(den)
{
    reduce();
}
 
Rational::Rational(double r)
    : numerator(static_cast<int>(r * 10000)), denominator(10000)
{
    reduce();
}
 
Rational& Rational::operator =(Rational const& that)
{
    this->numerator = that.numerator;
    this->denominator = that.denominator;
    return *this;
}
 
float Rational::as_float()
{
    return static_cast<float>(numerator) / denominator;
}
 
double Rational::as_double()
{
    return static_cast<double>(numerator) / denominator;
}
 
long double Rational::as_long_double()
{
    return static_cast<long double>(numerator) / denominator;
}
 
///为分子、分母赋值并约分
void Rational::assign(int num, int den)
{
    numerator = num;
    denominator = den;
    reduce();
}
 
///约分
void Rational::reduce()
{
    assert(denominator!=0);
    if(denominator < 0)
    {
        denominator = -denominator;
        numerator = -numerator;
    }
    int div(gcd(numerator, denominator));
    numerator = numerator / div;
    denominator = denominator / div;
}
 
///有理数的绝对值
Rational abs(Rational const & r)
{
    return (std::abs(r.numerator), r.denominator);
}
 
///将有理数取反的单目操作
Rational operator-(Rational const& r)
{
    return Rational(-r.numerator, r.denominator);
}
 
///有理数相加
Rational operator+(Rational const& lhs, Rational const& rhs)
{
    return Rational(lhs.numerator*rhs.denominator+rhs.numerator*lhs.denominator,
                        lhs.denominator*rhs.denominator);
}
 
///有理数想减
Rational operator-(Rational const& lhs, Rational const& rhs)
{
    return Rational(lhs.numerator*rhs.denominator-rhs.numerator*lhs.denominator,
                        lhs.denominator*rhs.denominator);
}
 
///有理数相乘
Rational operator*(Rational const& lhs, Rational const& rhs)
{
    return Rational(lhs.numerator*rhs.numerator, lhs.denominator*rhs.denominator);
}
 
///有理数相除
///检测除零错误
Rational operator/(Rational const& lhs, Rational const& rhs)
{
    return Rational(lhs.numerator*rhs.denominator, lhs.numerator*rhs.numerator);
}
 
///比较两个有理数是否相等
bool operator==(Rational const& a, Rational const& b)
{
    return a.numerator == b.numerator and a.denominator == b.denominator;
}
 
///比较两个有理数是否不等
bool operator!=(Rational const& a, Rational const& b)
{
    return not (a == b);
}
 
///比较两个有理数是否小于关系
bool operator<(Rational const& a, Rational const& b)
    {
        return a.numerator*b.denominator < b.numerator*a.denominator;
    }
 
///比较两个有理数是否是小于等于关系
bool operator<=(Rational const& a, Rational const& b)
{
    return not (b < a);
}
 
///比较两个有理数是否是大于关系
bool operator>(Rational const& a, Rational const& b)
{
    return b < a;
}
 
///比较两个有理数是否是大于等于关系
bool operator>=(Rational const& a, Rational const& b)
{
    return not (b > a);
}
 
///读取有理数
///格式为@em 整数 @c / @em 整数
std::istream& operator >>(std::istream& in, Rational& rat)
{
    int n(0), d(0);
    char sep('\0');
    if (not (in >> n >> sep))
        // 读取分子或分隔符出错
        in.setstate(in.failbit);
    else if (sep !='/')
    {
        // 成功读取分子,但其后无/。
        // 将读取的sep放回输入流,以备下次读取。
        in.unget();
        rat.assign(n, 1);
    }
    else if (in >> d)
        // 成功读取分子、分隔符及分母
        rat.assign(n, d);
    else
        in.setstate(in.failbit);
    return in;
}
 
///写出有理数
///格式为@em 分子 @c / @em 分母
std::ostream& operator<<(std::ostream& out, Rational const& rat)
{
    std::ostringstream tmp;
    tmp << rat.numerator << '/' << rat.denominator;
    out << tmp.str();
 
    return out;
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值