基本类型封装-有理数

分数也称作有理数,两个分数四则运算的结果仍然是分数

不希望看到 1/6 + 1/6 的结果是分数的近似值 0.333,而是1/3

有理数有两个重要的成员:分子和分母,还有重要的四则运算

自定义Rational类实现对有理数的封装,Rational类的UML图如下

在这里插入图片描述

/**
 * 自定义有理数类 Rational
 */
public class Rational {

    // 赋初值,保证分母不为零,分数值为零
    private int numerator = 0;   // 分子
    private int denominator = 1; // 分母

    /**
     * 设置分数的分子、分母
     * 保证操作数、运算结果均为最简分数,最大公约数
     *
     * @param a
     * @param b
     */
    public void setNumeratorAndDenominator(int a, int b) {
        if (b == 0) {
            // 运行时异常,编译器不要求必须处理
            // 分数的分子可以为零,分母不能为零
            throw new RuntimeException("分数不合法,分母为零");
        }
        int divisor = getGreatestCommonDivisor(Math.abs(a), Math.abs(b));
        numerator = a / divisor;
        denominator = b / divisor;
        // 处理符号问题 eg。-1/-6 显示成 1/6
        if (numerator < 0 && denominator < 0) { 
            numerator = -numerator;
            denominator = -denominator;
        }
        // 后台逻辑 eg。1/7-1/7=0/49,分数合法
        // 前台页面处理分子为零,结果显示成数字零
    }

    public int getNumerator() {
        return numerator;
    }

    public int getDenominator() {
        return denominator;
    }

    /**
     * 辗转相除:求两【正整数】最大公约数
     * 算法思路:r=m%n,m=n,n=r;r=0,返回n
     *
     * @param m
     * @param n
     * @return
     */
    static int getGreatestCommonDivisor(int m, int n) {
        int r = m % n;
        while (r != 0) {
            m = n;
            n = r;
            r = m % n;
        }
        return n;
    }

    /**
     * 加法运算
     *
     * @param r
     * @return
     */
    public Rational add(Rational r) {
        int a = r.getNumerator();   // 参数分子
        int b = r.getDenominator(); // 参数分母
        int newDenominator = denominator * b;               // 新分母
        int newNumerator = numerator * b + a * denominator; // 新分子
        Rational result = new Rational();
        result.setNumeratorAndDenominator(newNumerator, newDenominator);
        return result;
    }

    /**
     * 减法运算
     *
     * @param r
     * @return
     */
    public Rational sub(Rational r) {
        int a = r.getNumerator();   // 参数分子
        int b = r.getDenominator(); // 参数分母
        int newDenominator = denominator * b;               // 新分母
        int newNumerator = numerator * b - a * denominator; // 新分子
        Rational result = new Rational();
        result.setNumeratorAndDenominator(newNumerator, newDenominator);
        return result;
    }

    /**
     * 乘法运算
     *
     * @param r
     * @return
     */
    public Rational muti(Rational r) {
        int a = r.getNumerator();   // 参数分子
        int b = r.getDenominator(); // 参数分母
        int newNumerator = numerator * a;     // 新分子
        int newDenominator = denominator * b; // 新分母
        Rational result = new Rational();
        result.setNumeratorAndDenominator(newNumerator, newDenominator);
        return result;
    }

    /**
     * 除法运算
     *
     * @param r
     * @return
     */
    public Rational div(Rational r) {
        int a = r.getNumerator();   // 参数分子
        int b = r.getDenominator(); // 参数分母
        int newNumerator = numerator * b;     // 新分子
        int newDenominator = denominator * a; // 新分母
        Rational result = new Rational();
        result.setNumeratorAndDenominator(newNumerator, newDenominator);
        return result;
    }
}

一、计算 1/5 和 3/2 四则运算的结果

        Rational rational1 = new Rational();
        rational1.setNumeratorAndDenominator(1, 5);

        Rational rational2 = new Rational();
        rational2.setNumeratorAndDenominator(3, 2);

        Rational add = rational1.add(rational2); 
        System.out.println(add.getNumerator() + "/" + add.getDenominator()); // 17/10

        Rational sub = rational1.sub(rational2); 
        System.out.println(sub.getNumerator() + "/" + sub.getDenominator()); // -13/10 

        Rational muti = rational1.muti(rational2); 
        System.out.println(muti.getNumerator() + "/" + muti.getDenominator()); // 3/10

        Rational div = rational1.div(rational2);
        System.out.println(div.getNumerator() + "/" + div.getDenominator());// 2/15

二、求2/1+3/2+5/3+8/5…的前10项和

		Rational sum = new Rational();
        Rational item = new Rational();
        item.setNumeratorAndDenominator(2, 1);
        // for循环实现
        for (int i = 0; i < 10; i++) { // 校验循环,序缩小次数
            sum = sum.add(item);
            int fenzi = item.getNumerator(); // 修改中间量
            int fenmu = item.getDenominator();
            item.setNumeratorAndDenominator(fenzi + fenmu, fenzi);
        }
        // while循环实现
        /*int index = 1, end = 10; // 检验循环,缩小次数
        while (index <= end) {
            sum = sum.add(item);
            index++;
            int fenzi = item.getNumerator();  // 修改中间量
            int fenmu = item.getDenominator();
            item.setNumeratorAndDenominator(fenzi + fenmu, fenzi);
        }*/
        int a = sum.getNumerator();
        int b = sum.getDenominator();
        System.out.println("分数表示:" + a + "/" + b);   // 998361233/60580520
        System.out.println("小数表示:" + a / (b * 1.0)); // 16.479905306194137
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

鱼悠奕

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

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

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

打赏作者

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

抵扣说明:

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

余额充值