由于程序中的浮点数不能准确表示一些实数,经过多次运算后会存在精度丢失导致计算结果越来越不准确的问题,这时可以考虑使用分数来进行数据的存储与运算,使用分数可以保证经过多次运算最终可以得到准确的结果。
实现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;
}
}
本文介绍了一个Java类Fraction的实现,该类能够精确地处理分数的加、减、乘、除等基本运算,并提供了多种用于比较和判断分数性质的方法。
698

被折叠的 条评论
为什么被折叠?



