Java实现分数

时间: 2024-11-10 admin IT培训

Java实现分数

Java实现分数

自己独立实现的,如果有bug或者错误,欢迎评论区留言!

文章目录

  • 文档
  • 代码

文档

字段摘要:

修饰符字段解释
static final FractionONE分数:1,分子、分母都是1的分数
static final FractionZERO分数:0,分子是0、分母是1的分数

构造方法摘要 :

构造方法解释
Fraction(String fractionStr)根据字符串生成一个分数,支持识别”/"、小数点
Fraction(double numerator)根据一个double数生成一个分数
Fraction(long numerator)根据一个整型数字生成一个分数;分子式该数字,分母是1
Fraction(long numerator, long denominator)根据提供的分子、分母生成分数;numerator:分子,denominator:分母

方法摘要 :

修饰符方法解释
intintValue()返回对应分数的int值
longlongValue()返回对应分数的long 值
floatfloatValue()返回对应分数的float 值
doubledoubleValue()返回对应分数的double 值
intcompareTo(Fraction o)和另一个分数比大小
StringtoString()以假分数形式返回分数,使用”/“作为分号
Fractionadd(Fraction fraction)返回两个分数的和,不会改编原分数
Fractionsub(Fraction fraction)返回两个分数的差,不会改编原分数
Fractionmul(Fraction fraction)返回两个分数的积,不会改编原分数
Fractiondiv(Fraction fraction)返回两个分数的商,不会改编原分数
Fractionclone()返回一个克隆对象,深拷贝
FractiongetOppositeNumber(Fraction fraction)返回参数的相反数,a的相反数是-a
FractiongetReciprocal(Fraction fraction)返回参数的倒数,a的倒数是1/a
booleanisZero()判断该分数是否为0
longgetNumerator()获取分子
longgetDenominator()获取分母
voidsetNumerator(long numerator)设置新的分子
voidsetDenominator(long denominator)设置新的分母

代码

/*** @description: 分数* @author: liangjiayy* @create: 2022-09-30 23:31**/
public class Fraction extends Number implements Comparable<Fraction>, Operationable<Fraction> {/*** 1*/public static final Fraction ONE = new Fraction(1);/*** 0*/public static final Fraction ZERO = new Fraction(0);/*** 分子*/private long numerator;/*** 分母*/private long denominator;public Fraction(String fractionStr) {String[] split = fractionStr.trim().split("/");if (split.length > 2 || split.length == 0) {throw new RuntimeException("将\"" + fractionStr + "\"转化为分数出现了异常!");}Fraction num, den;//分子if (split[0].contains(".")) {num = convertDouble2fraction(Double.parseDouble(split[0]));} else {num = new Fraction(Long.parseLong(split[0]));}//分母if (split.length == 2) {if (split[1].contains(".")) {den = convertDouble2fraction(Double.parseDouble(split[1]));} else {den = new Fraction(Long.parseLong(split[1]));}} else {this.numerator = num.numerator;this.denominator = num.denominator;return;}Fraction div = num.div(den);this.numerator = div.numerator;this.denominator = div.denominator;}public Fraction(double numerator) {Fraction fraction = convertDouble2fraction(numerator);this.numerator = fraction.numerator;this.denominator = fraction.denominator;}private Fraction convertDouble2fraction(double numerator) {String[] split = (numerator + "").split("\\.");//整数部分long left = Long.parseLong(split[0]);//小数部分long right = Long.parseLong(split[1]);int len = split[1].length();long pow = (long) Math.pow(10, len);return new Fraction(left * pow + right, pow);}public Fraction(long numerator) {this(numerator, 1L);}public Fraction(long numerator, long denominator) {this.numerator = numerator;this.denominator = denominator;}/*** Returns the value of the specified number as an {@code int},* which may involve rounding or truncation.** @return the numeric value represented by this object after conversion* to type {@code int}.*/@Overridepublic int intValue() {return (int) (numerator / denominator);}/*** Returns the value of the specified number as a {@code long},* which may involve rounding or truncation.** @return the numeric value represented by this object after conversion* to type {@code long}.*/@Overridepublic long longValue() {return numerator / denominator;}/*** Returns the value of the specified number as a {@code float},* which may involve rounding.** @return the numeric value represented by this object after conversion* to type {@code float}.*/@Overridepublic float floatValue() {return (float) (1.0 * numerator / denominator);}/*** Returns the value of the specified number as a {@code double},* which may involve rounding.** @return the numeric value represented by this object after conversion* to type {@code double}.*/@Overridepublic double doubleValue() {return 1.0 * numerator / denominator;}/*** Compares this object with the specified object for order.  Returns a* negative integer, zero, or a positive integer as this object is less* than, equal to, or greater than the specified object.** <p>The implementor must ensure <tt>sgn(xpareTo(y)) ==* -sgn(ypareTo(x))</tt> for all <tt>x</tt> and <tt>y</tt>.  (This* implies that <tt>xpareTo(y)</tt> must throw an exception iff* <tt>ypareTo(x)</tt> throws an exception.)** <p>The implementor must also ensure that the relation is transitive:* <tt>(xpareTo(y)&gt;0 &amp;&amp; ypareTo(z)&gt;0)</tt> implies* <tt>xpareTo(z)&gt;0</tt>.** <p>Finally, the implementor must ensure that <tt>xpareTo(y)==0</tt>* implies that <tt>sgn(xpareTo(z)) == sgn(ypareTo(z))</tt>, for* all <tt>z</tt>.** <p>It is strongly recommended, but <i>not</i> strictly required that* <tt>(xpareTo(y)==0) == (x.equals(y))</tt>.  Generally speaking, any* class that implements the <tt>Comparable</tt> interface and violates* this condition should clearly indicate this fact.  The recommended* language is "Note: this class has a natural ordering that is* inconsistent with equals."** <p>In the foregoing description, the notation* <tt>sgn(</tt><i>expression</i><tt>)</tt> designates the mathematical* <i>signum</i> function, which is defined to return one of <tt>-1</tt>,* <tt>0</tt>, or <tt>1</tt> according to whether the value of* <i>expression</i> is negative, zero or positive.** @param o the object to be compared.* @return a negative integer, zero, or a positive integer as this object* is less than, equal to, or greater than the specified object.* @throws NullPointerException if the specified object is null* @throws ClassCastException   if the specified object's type prevents it*                              from being compared to this object.*/@Overridepublic int compareTo(Fraction o) {Fraction[] fractions = convert2sameDenominator(this, o);//如果分母是正数,比较分子if (fractions[0].denominator > 0) {return Longpare(fractions[0].numerator, fractions[1].numerator);}return -Longpare(fractions[0].numerator, fractions[1].numerator);}/*** 通分,将两个分数转化成同分母分数** @param f1* @param f2* @return Fraction[0]:第一个分数转化后的结果,Fraction[1]:第二个分母转化后的结果*/private Fraction[] convert2sameDenominator(Fraction f1, Fraction f2) {//找公倍数long leastCommonMultiple = findLeastCommonMultiple(f1.denominator, f2.denominator);Fraction[] res = new Fraction[2];//转化为指定的分母res[0] = convertDenominator(f1, leastCommonMultiple);res[1] = convertDenominator(f2, leastCommonMultiple);return res;}/*** 将分数的分母转化为指定的值* 注意:新的分母必须是旧的分母的倍数** @param fraction* @param denominator 新的分母* @return*/private Fraction convertDenominator(Fraction fraction, long denominator) {if (denominator % fraction.denominator != 0) {throw new RuntimeException("无法将\"" + fraction + "\"转化为分母为" + denominator + "的分数!");}return new Fraction(fraction.numerator * (denominator / fraction.denominator), denominator);}/*** 找最小公倍数** @param num1* @param num2* @return*/private long findLeastCommonMultiple(long num1, long num2) {//找公因数long greatestCommonDivisor = findGreatestCommonDivisor(num1, num2);//公倍数return num1 * num2 / greatestCommonDivisor;}/*** 找最大公因数** @param num1* @param num2* @return*/private long findGreatestCommonDivisor(long num1, long num2) {//辗转相除法long tmp;while (num2 != 0) {tmp = num1 % num2;num1 = num2;num2 = tmp;}return num1;}@Overridepublic String toString() {Fraction fraction = convert2theSimplestFraction(this);this.numerator = fraction.numerator;this.denominator = fraction.denominator;//分母等于1,只返回分子if (denominator == 1) {return numerator + "";}if (numerator == 0) {return 0 + "";}return numerator + "/" + denominator;}/*** 加法** @param fraction* @return*/@Overridepublic Fraction add(Fraction fraction) {//通分Fraction[] fractions = convert2sameDenominator(this, fraction);//分子相加Fraction res = new Fraction(fractions[0].numerator + fractions[1].numerator, fractions[0].denominator);//化简为最简带分数return convert2theSimplestFraction(res);}/*** Creates and returns a copy of this object.  The precise meaning* of "copy" may depend on the class of the object. The general* intent is that, for any object {@code x}, the expression:* <blockquote>* <pre>* x.clone() != x</pre></blockquote>* will be true, and that the expression:* <blockquote>* <pre>* x.clone().getClass() == x.getClass()</pre></blockquote>* will be {@code true}, but these are not absolute requirements.* While it is typically the case that:* <blockquote>* <pre>* x.clone().equals(x)</pre></blockquote>* will be {@code true}, this is not an absolute requirement.* <p>* By convention, the returned object should be obtained by calling* {@code super.clone}.  If a class and all of its superclasses (except* {@code Object}) obey this convention, it will be the case that* {@code x.clone().getClass() == x.getClass()}.* <p>* By convention, the object returned by this method should be independent* of this object (which is being cloned).  To achieve this independence,* it may be necessary to modify one or more fields of the object returned* by {@code super.clone} before returning it.  Typically, this means* copying any mutable objects that comprise the internal "deep structure"* of the object being cloned and replacing the references to these* objects with references to the copies.  If a class contains only* primitive fields or references to immutable objects, then it is usually* the case that no fields in the object returned by {@code super.clone}* need to be modified.* <p>* The method {@code clone} for class {@code Object} performs a* specific cloning operation. First, if the class of this object does* not implement the interface {@code Cloneable}, then a* {@code CloneNotSupportedException} is thrown. Note that all arrays* are considered to implement the interface {@code Cloneable} and that* the return type of the {@code clone} method of an array type {@code T[]}* is {@code T[]} where T is any reference or primitive type.* Otherwise, this method creates a new instance of the class of this* object and initializes all its fields with exactly the contents of* the corresponding fields of this object, as if by assignment; the* contents of the fields are not themselves cloned. Thus, this method* performs a "shallow copy" of this object, not a "deep copy" operation.* <p>* The class {@code Object} does not itself implement the interface* {@code Cloneable}, so calling the {@code clone} method on an object* whose class is {@code Object} will result in throwing an* exception at run time.** @return a clone of this instance.* @throws CloneNotSupportedException if the object's class does not*                                    support the {@code Cloneable} interface. Subclasses*                                    that override the {@code clone} method can also*                                    throw this exception to indicate that an instance cannot*                                    be cloned.* @see Cloneable*/@Overrideprotected Fraction clone() {return new Fraction(this.numerator, this.denominator);}/*** 约分** @param fraction* @return*/private Fraction convert2theSimplestFraction(Fraction fraction) {long leastCommonMultiple = findGreatestCommonDivisor(fraction.numerator, fraction.denominator);if (leastCommonMultiple == 1) {return fraction.clone();}//分子分母,同时除以最大公约数return new Fraction(fraction.numerator / leastCommonMultiple, fraction.denominator / leastCommonMultiple);}/*** 减法** @param fraction* @return*/@Overridepublic Fraction sub(Fraction fraction) {// 相反数fraction = getOppositeNumber(fraction);return add(fraction);}/*** 相反数** @param fraction* @return*/@Overridepublic Fraction getOppositeNumber(Fraction fraction) {return new Fraction(-fraction.numerator, fraction.denominator);}/*** 乘法** @param fraction* @return*/@Overridepublic Fraction mul(Fraction fraction) {Fraction res = new Fraction(numerator * fraction.numerator, denominator * fraction.denominator);return convert2theSimplestFraction(res);}/*** 除法** @param fraction* @return*/@Overridepublic Fraction div(Fraction fraction) {fraction = getReciprocal(fraction);return mul(fraction);}/*** 倒数** @param fraction* @return*/@Overridepublic Fraction getReciprocal(Fraction fraction) {return new Fraction(fraction.denominator, fraction.numerator);}public boolean isZero() {return this.numerator == 0;}/*** 分子** @return*/public long getNumerator() {return numerator;}/*** 分母** @return*/public long getDenominator() {return denominator;}public void setNumerator(long numerator) {this.numerator = numerator;}public void setDenominator(long denominator) {this.denominator = denominator;}
}/*** 支持运算的,包括加、减、乘、除*/
interface Operationable<T> {/*** 加法** @param t* @return*/T add(T t);/*** 减法** @param t* @return*/T sub(T t);/*** 乘法** @param t* @return*/T mul(T t);/*** 除法** @param t* @return*/T div(T t);/*** 相反数** @param fraction* @return*/Fraction getOppositeNumber(Fraction fraction);/*** 倒数** @param fraction* @return*/Fraction getReciprocal(Fraction fraction);
}