分数的java实现

本文介绍了一个Java类Fraction的实现,该类能够精确地处理分数的加、减、乘、除等基本运算,并提供了多种用于比较和判断分数性质的方法。

由于程序中的浮点数不能准确表示一些实数,经过多次运算后会存在精度丢失导致计算结果越来越不准确的问题,这时可以考虑使用分数来进行数据的存储与运算,使用分数可以保证经过多次运算最终可以得到准确的结果。

实现class Fraction,保存分子numerator与分母denominator的值(保存前完成化简),并依次实现以下方法:

add:分数相加

subtract:分数相减

multiply:分数相乘

divide:分数相除

opposite:得到相反数

reciprocal:得到倒数

isInfinite:判断分数是否是无穷大

isZero:判断分数是否为零

isPositive:判断分数是否是正数

isNegative:判断分数是否是负数

compareTo:比较两个分数的大小

gcd:求最大公约数,用来化简分数

java代码实现

public class Fraction implements Comparable<Fraction> {

    public static final Fraction ZERO = new Fraction(0, 1);
    public static final Fraction POSITIVE_INFINITE = new Fraction(1, 0);
    public static final Fraction NEGATIVE_INFINITE = new Fraction(-1, 0);

    public final int numerator;
    public final int denominator;

    public Fraction(int numerator, int denominator) {
        if (numerator == 0 && denominator == 0) {
            throw new IllegalArgumentException("Numerator and denominator can't both be 0!");
        } else if (denominator == 0) {  // infinite
            this.numerator = numerator < 0 ? -1 : 1;
            this.denominator = 0;
        } else if (numerator == 0) {  // zero
            this.numerator = 0;
            this.denominator = 1;
        } else {
            if (denominator < 0) {
                numerator = -numerator;
                denominator = -denominator;
            }
            int gcd = gcd(numerator, denominator);
            this.numerator = numerator / gcd;
            this.denominator = denominator / gcd;
        }
    }

    public Fraction add(Fraction f) {
        if (isInfinite() && f.isInfinite()) {
            if ((isPositive() && f.isPositive()) || (isNegative() && f.isNegative())) return this;
            else return ZERO;
        }
        int gcd = gcd(denominator, f.denominator);
        int lcm = denominator / gcd * f.denominator;
        int num = numerator * (f.denominator / gcd) + f.numerator * (denominator / gcd);
        return new Fraction(num, lcm);
    }

    public Fraction subtract(Fraction f) {
        return add(f.opposite());
    }

    public Fraction multiply(Fraction f) {
        int num = numerator * f.numerator;
        int den = num == 0 ? 1 : denominator * f.denominator;
        return new Fraction(num, den);
    }

    public Fraction divide(Fraction f) {
        return multiply(f.reciprocal());
    }

    public Fraction opposite() {
        return new Fraction(-numerator, denominator);
    }

    public Fraction reciprocal() {  // NegativeInfinite's reciprocal's reciprocal is PositiveInfinite
        return new Fraction(denominator, numerator);
    }

    public boolean isInfinite() {
        return denominator == 0;
    }
    
    public boolean isZero() {
        return numerator == 0;
    }

    public boolean isPositive() {
        return numerator > 0;
    }

    public boolean isNegative() {
        return numerator < 0;
    }

    @Override
    public int compareTo(Fraction that) {
        if (this.equals(that)) return 0;
        else if (this.numerator < 0 && that.numerator > 0) return -1;
        else if (this.numerator > 0 && that.numerator < 0) return 1;
        else if ((this.isInfinite() && this.isPositive()) || (that.isInfinite() && that.isNegative())) return 1;
        else if ((this.isInfinite() && this.isNegative()) || (that.isInfinite() && that.isPositive())) return -1;
        int gcd = gcd(this.denominator, that.denominator);
        return Integer.compare(this.numerator * (that.denominator / gcd),
                that.numerator * (this.denominator / gcd));
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Fraction that = (Fraction) o;
        return this.numerator == that.numerator &&
                this.denominator == that.denominator;
    }

    @Override
    public int hashCode() {
        return 31 * numerator + denominator;
    }

    @Override
    public String toString() {
        return numerator + "/" + denominator;
    }

    public static int gcd(int a, int b) {
        a = Math.abs(a);
        b = Math.abs(b);
        while (a != 0 && b != 0) {
            if (a > b) a %= b;
            else b %= a;
        }
        return a == 0 ? b : a;
    }
}

源代码地址https://github.com/SSSxCCC/Algorithm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

SSSxCCC

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

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

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

打赏作者

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

抵扣说明:

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

余额充值