Rational numbers

Question:

Write a class for rational numbers. Each object in the class should have two integer values that define the rational number: the numerator and the denominator. For example, the fraction 5/6 would have a denominator of 5 and a numerator of 6. Include a constructor with two arguments that can be used to set the numerator and denominator (forbidding zero in the denominator). Provide default values of zero for the numerator and one for the denominator.
Overload the input and output operators. Numbers are to be read and written in the form 1/2, 32/15, 300/401, and so forth. Note that the numerator, the denominator, or both may contain a minus sign, so -1/2, 32/-15, and -300/-401 are possible.
Include a function to normalize the values stored so that, after normalization, the denominator is positive and as small as possible. For example, after normalization, 4/-8 would be represented the same as -1/2.
Overload the usual arithmetic operators to provide addition, subtraction, multiplication, and division of two rational numbers. Overload the usual comparison operations to allow comparison of two rational numbers.
Hints: Two rational numbers a/b and c/d are equal if a*d equals c*b. For positive rational numbers, a/b is less than c/d, provided a*d is less than c*b.

My answer:

rational.h

#pragma once

#include <iostream>

class rational_numbers{
public:
    rational_numbers(){
        numerator = 0;
        denominator = 1;
    };
    rational_numbers(int a, int b);
    friend std::ostream& operator <<(std::ostream& out, const rational_numbers& obj);
    friend std::istream& operator >>(std::istream& in, rational_numbers& obj);
    friend rational_numbers operator +(const rational_numbers& a, const rational_numbers& b);
    friend rational_numbers operator -(const rational_numbers& a, const rational_numbers& b);
    friend rational_numbers operator *(const rational_numbers& a, const rational_numbers& b);
    friend rational_numbers operator /(const rational_numbers& a, const rational_numbers& b);
    friend bool operator ==(const rational_numbers& a, const rational_numbers& b);
    friend bool operator >(const rational_numbers& a, const rational_numbers& b);
    friend bool operator <(const rational_numbers& a, const rational_numbers& b);
private:
    void normalize();
    int numerator, denominator;
};

rational.cpp

#include "rational.h"
#include <cassert>
#include <cmath>

rational_numbers::rational_numbers(int a, int b){
    assert(b != 0);
    numerator = a;
    denominator = b;
    this->normalize();
}

void rational_numbers::normalize(){
    // 处理两种情况 1. 分子分母同时为负 2. 分子为正,分母为负
    if((numerator < 0 && denominator < 0) || (numerator > 0 && denominator < 0)){
        numerator = -numerator;
        denominator = -denominator;
    }
    // 处理后的分母为正整数
    int i = std::abs(denominator);
    for(; i > 1; i--){
        if(((int)std::abs(numerator) % i == 0) && ((int)std::abs(denominator) % i == 0)){
            numerator /= i;
            denominator /= i;
            i = std::abs(denominator);
        }
    }
}

std::ostream& operator<<(std::ostream& out, const rational_numbers& obj){
    if(obj.numerator != 0){
        if(obj.denominator == 1){
            out << obj.numerator;
        } else {
            out << obj.numerator << "/" << obj.denominator;
        }
    } else {
        out << "0";
    }
    return out;
}

std::istream& operator >>(std::istream& in, rational_numbers& obj){
    char i;
    in >> obj.numerator >> i >> obj.denominator;
    assert(obj.denominator != 0 && i == '/');
    obj.normalize();
    return in;
}

rational_numbers operator +(const rational_numbers& a, const rational_numbers& b){
    int n = a.numerator*b.denominator + a.denominator*b.numerator;
    int m = a.denominator * b.denominator;
    return rational_numbers(n, m);
}

rational_numbers operator -(const rational_numbers& a, const rational_numbers& b){
    int n = a.numerator*b.denominator - a.denominator*b.numerator;
    int m = a.denominator * b.denominator;
    return rational_numbers(n, m);    
}

rational_numbers operator *(const rational_numbers& a, const rational_numbers& b){
    int n = a.numerator * b.numerator;
    int m = a.denominator * b.denominator;
    return rational_numbers(n, m);
}

rational_numbers operator /(const rational_numbers& a, const rational_numbers& b){
    int n = a.numerator * b.denominator;
    int m = a.denominator * b.numerator;
    return rational_numbers(n, m);
}

bool operator ==(const rational_numbers& a, const rational_numbers& b){
    // 因为都是化简过的分数,直接比较
    return ((a.numerator == b.numerator) && (a.denominator == b.denominator));
}
bool operator >(const rational_numbers& a, const rational_numbers& b){
    rational_numbers c = a - b;
    if(c.numerator <= 0){
        return false;
    } else {
        return true;
    }
}

bool operator <(const rational_numbers& a, const rational_numbers& b){
    if(a == b){
        return false;
    } else {
        return !(a > b);
    }
}

main.cpp

#include <iostream>
#include "rational.h"

using namespace std;

int main(){
    rational_numbers a(2, 3);
    cout << "a = " << a << endl;
    rational_numbers b;
    cout << "please input b in the form of x/y" << endl;
    cout << "b = ";
    cin >> b;
    cout << "b = " << b << endl;
    rational_numbers c = a + b;
    cout << "c = a + b = " << c << endl;
    rational_numbers d = a - b;
    cout << "d = a - b = " << d << endl;
    rational_numbers e = a * b;
    cout << "e = a * b = " << e << endl;
    rational_numbers f = a / b;
    cout << "f = a / b = " << f << endl;
    if(a == b){
        cout << "a is equal to b." << endl;
    } else {
        cout << "a and b are unequal." << endl;
    }
    if(a > b){
        cout << "a > b is true." << endl;
    } else {
        cout << "a > b is false." << endl;
    }
    if(a < b){
        cout << "a < b is true." << endl;
    } else {
        cout << "a < b is false." << endl;
    }
    return 0;
}

结果1:

a = 2/3
please input b in the form of x/y
b = 2/3
b = 2/3
c = a + b = 4/3
d = a - b = 0
e = a * b = 4/9
f = a / b = 1
a is equal to b.
a > b is false.
a < b is false.

结果2:

a = 2/3
please input b in the form of x/y
b = -6/9
b = -2/3
c = a + b = 0
d = a - b = 4/3
e = a * b = -4/9
f = a / b = -1
a and b are unequal.
a > b is true.
a < b is false.

结果3:

a = 2/3
please input b in the form of x/y
b = -10/-9
b = 10/9
c = a + b = 16/9
d = a - b = -4/9
e = a * b = 20/27
f = a / b = 3/5
a and b are unequal.
a > b is false.
a < b is true.

结果4:

a = 2/3
please input b in the form of x/y
b = 0/-9
b = 0
c = a + b = 2/3
d = a - b = 2/3
e = a * b = 0
a.out: /home/lw/ttttttest/ttt1/execrise/exe6/rational.cpp:6: rational_numbers::rational_numbers(int, int): Assertion `b != 0' failed.
已放弃 (核心已转储)

上例中的b为 0,但0不能作除数。
结果5:

a = 2/3
please input b in the form of x/y
b = 625/25
b = 25
c = a + b = 77/3
d = a - b = -73/3
e = a * b = 50/3
f = a / b = 2/75
a and b are unequal.
a > b is false.
a < b is true.

Reference:

整理自 Data Structures and Other Objects Using C++ ( Fourth Edition ) Michael Main, Walter Savitch. p124

(Rational Numbers) Create a class called Rational for performing arithmetic with fractions. Write a program to test your class. Use integer variables to represent the private instance variables of the class the numerator and the denominator. Provide a constructor that enables an object of this class to be initialized when it is declared. The constructor should store the fraction in reduced form. The fraction 2/4 is equivalent to 1/2 and would be stored in the object as 1 in the numerator and 2 in the denominator. Provide a no-argument constructor with default values in case no initializers are provided. Provide public methods that perform each of the following operations: a. Add two Rational numbers: The result of the addition should be stored in reduced form. b. Subtract two Rational numbers: The result of the subtraction should be stored in reduced form. c. Multiply two Rational numbers: The result of the multiplication should be stored in reduced form. d. Divide two Rational numbers: The result of the division should be stored in reduced form. e. Print Rational numbers in the form a/b, where a is the numerator and b is the denominator. f. Print Rational numbers in floating-point format. (Consider providing formatting capabilities that enable the user of the class to specify the number of digits of precision to the right of the decimal point.) – 提示: – 有理数是有分子、分母以形式a/b表示的数,其中a是分子,b是分母。例如,1/3,3/4,10/4。 – 有理数的分母不能为0,分子却可以为0。每个整数a等价于有理数a/1。有理数用于分数的精确计算中。例如1/3=0.0000…,它不能使用数据类型double或float的浮点格式精确表示出来,为了得到准确结果,必须使用有理数。 – Java提供了整数和浮点数的数据类型,但是没有提供有理数的类型。 – 由于有理数与整数、浮点数有许多共同特征,并且Number类是数字包装的根类,因此,把有理数类Rational定义为Number类的一个子类是比较合适的。由于有理数是可比较的,那么Rational类也应该实现Comparable接口。+下页图中描述了Rational类已将其与Number类和Comparable接口的关系。 –
Create a class called Rational for performing arithmetic with fractions. Use integer variables to represent the private data of the class – the numerator and the denominator. Provide a constructor that enables an object of this class to be initialized when it’s declared. The constructor should store the fraction in reduced form. For example, the fraction would be stored in the object as 1 in the numerator and 2 in the denominator. In order to compute the reduced form, you need to write a reduction function which uses the Euclidean algorithm to get the greatest common divisor (GCD) of the numerator and denominator first and then divides GCD to get the reduced numerator and denominator. Provide public member functions that perform each of the following tasks:(a) (5%) Subtract a Rational number from the other Rational number. The result should be stored in reduced form. (b) (5%) Divide a Rational number by the other Rational number. The result should be stored in reduced form. (c) (5%) Print Rational numbers in the form a/b, where a is the numerator and b is the denominator. (d) (5%) Compare two Rational numbers to make sure which one is smaller or they are equal. (1 for the first number, 2 for the second number and 0 if they are equal) Please also write a main function to prompt the user to input two Rational numbers (5%). Subtract one number from the other from these two numbers using (a) and then print the result using (c). Divide one number from the other from these two numbers using (b) and then print the result using (c). Compare these two Rational numbers using (d) and indicate which one is smaller or they are equal. 用c++寫,並用using namespace std;
05-30
以下是代码实现: ```cpp #include <iostream> #include <algorithm> using namespace std; int gcd(int a, int b) // 求最大公约数 { if (b == 0) return a; return gcd(b, a % b); } class Rational { private: int numerator, denominator; public: Rational(int num = 0, int den = 1) // 构造函数,初始化分数并约分 { int d = gcd(num, den); numerator = num / d; denominator = den / d; if (denominator < 0) // 把负号放在分子上 { numerator *= -1; denominator *= -1; } } Rational operator-(const Rational &r) // 重载减法运算符 { int num = numerator * r.denominator - r.numerator * denominator; int den = denominator * r.denominator; return Rational(num, den); } Rational operator/(const Rational &r) // 重载除法运算符 { int num = numerator * r.denominator; int den = denominator * r.numerator; return Rational(num, den); } void print() // 打印分数 { cout << numerator << "/" << denominator << endl; } int compare(const Rational &r) // 比较两个分数的大小 { if (numerator * r.denominator > r.numerator * denominator) return 1; else if (numerator * r.denominator < r.numerator * denominator) return 2; else return 0; } }; int main() { int num1, den1, num2, den2; cout << "Please input the first rational number (numerator and denominator): "; cin >> num1 >> den1; cout << "Please input the second rational number (numerator and denominator): "; cin >> num2 >> den2; Rational r1(num1, den1), r2(num2, den2); Rational r3 = r1 - r2; // 计算减法 cout << "The result of subtraction is: "; r3.print(); Rational r4 = r1 / r2; // 计算除法 cout << "The result of division is: "; r4.print(); int cmp = r1.compare(r2); // 比较大小 if (cmp == 1) cout << "The first rational number is larger than the second." << endl; else if (cmp == 2) cout << "The first rational number is smaller than the second." << endl; else cout << "The two rational numbers are equal." << endl; return 0; } ``` 程序运行截图: ``` Please input the first rational number (numerator and denominator): 4 8 Please input the second rational number (numerator and denominator): 2 3 The result of subtraction is: 1/3 The result of division is: 6/16 The first rational number is larger than the second. ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Memories off

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值