猿问
下载APP

表示Java分数的最佳方法?

我正在尝试使用Java中的分数。


我想实现算术函数。为此,我首先需要一种将功能标准化的方法。我知道我只有一个公分母才能将1/6和1/2加起来。我将不得不添加1/6和3/6。天真的方法会让我加2/12和6/12,然后减少。如何以最少的性能损失获得一个共同的分母?哪种算法最适合?


版本8(感谢hstoerr):


改进包括:


现在equals()方法与compareTo()方法一致

final class Fraction extends Number {

    private int numerator;

    private int denominator;


    public Fraction(int numerator, int denominator) {

        if(denominator == 0) {

            throw new IllegalArgumentException("denominator is zero");

        }

        if(denominator < 0) {

            numerator *= -1;

            denominator *= -1;

        }

        this.numerator = numerator;

        this.denominator = denominator;

    }


    public Fraction(int numerator) {

        this.numerator = numerator;

        this.denominator = 1;

    }


    public int getNumerator() {

        return this.numerator;

    }


    public int getDenominator() {

        return this.denominator;

    }


    public byte byteValue() {

        return (byte) this.doubleValue();

    }


    public double doubleValue() {

        return ((double) numerator)/((double) denominator);

    }


    public float floatValue() {

        return (float) this.doubleValue();

    }


    public int intValue() {

        return (int) this.doubleValue();

    }


    public long longValue() {

        return (long) this.doubleValue();

    }


    public short shortValue() {

        return (short) this.doubleValue();

    }


    public boolean equals(Fraction frac) {

        return this.compareTo(frac) == 0;

    }


    public int compareTo(Fraction frac) {

        long t = this.getNumerator() * frac.getDenominator();

        long f = frac.getNumerator() * this.getDenominator();

        int result = 0;

        if(t>f) {

            result = 1;

        }

        else if(f>t) {

            result = -1;

        }

        return result;

    }

}



慕标琳琳
浏览 127回答 3
3回答

ABOUTYOU

碰巧的是,不久前我为欧拉计划问题写了一个BigFraction类。它保留了BigInteger分子和分母,因此它永远不会溢出。但是,对于许多您永远不会溢出的操作来说,这会有点慢。无论如何,请根据需要使用它。我一直很想以某种方式炫耀它。:)编辑:该代码的最新,最出色的版本,包括单元测试,现在托管在GitHub上,也可以通过Maven Central获得。我将原始代码留在这里,以便此答案不仅仅是一个链接...import java.math.*;/**&nbsp;* Arbitrary-precision fractions, utilizing BigIntegers for numerator and&nbsp;* denominator.&nbsp; Fraction is always kept in lowest terms.&nbsp; Fraction is&nbsp;* immutable, and guaranteed not to have a null numerator or denominator.&nbsp;* Denominator will always be positive (so sign is carried by numerator,&nbsp;* and a zero-denominator is impossible).&nbsp;*/public final class BigFraction extends Number implements Comparable<BigFraction>{&nbsp; private static final long serialVersionUID = 1L; //because Number is Serializable&nbsp; private final BigInteger numerator;&nbsp; private final BigInteger denominator;&nbsp; public final static BigFraction ZERO = new BigFraction(BigInteger.ZERO, BigInteger.ONE, true);&nbsp; public final static BigFraction ONE = new BigFraction(BigInteger.ONE, BigInteger.ONE, true);&nbsp; /**&nbsp; &nbsp;* Constructs a BigFraction with given numerator and denominator.&nbsp; Fraction&nbsp; &nbsp;* will be reduced to lowest terms.&nbsp; If fraction is negative, negative sign will&nbsp; &nbsp;* be carried on numerator, regardless of how the values were passed in.&nbsp; &nbsp;*/&nbsp; public BigFraction(BigInteger numerator, BigInteger denominator)&nbsp; {&nbsp; &nbsp; if(numerator == null)&nbsp; &nbsp; &nbsp; throw new IllegalArgumentException("Numerator is null");&nbsp; &nbsp; if(denominator == null)&nbsp; &nbsp; &nbsp; throw new IllegalArgumentException("Denominator is null");&nbsp; &nbsp; if(denominator.equals(BigInteger.ZERO))&nbsp; &nbsp; &nbsp; throw new ArithmeticException("Divide by zero.");&nbsp; &nbsp; //only numerator should be negative.&nbsp; &nbsp; if(denominator.signum() < 0)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; numerator = numerator.negate();&nbsp; &nbsp; &nbsp; denominator = denominator.negate();&nbsp; &nbsp; }&nbsp; &nbsp; //create a reduced fraction&nbsp; &nbsp; BigInteger gcd = numerator.gcd(denominator);&nbsp; &nbsp; this.numerator = numerator.divide(gcd);&nbsp; &nbsp; this.denominator = denominator.divide(gcd);&nbsp; }&nbsp; /**&nbsp; &nbsp;* Constructs a BigFraction from a whole number.&nbsp; &nbsp;*/&nbsp; public BigFraction(BigInteger numerator)&nbsp; {&nbsp; &nbsp; this(numerator, BigInteger.ONE, true);&nbsp; }&nbsp; public BigFraction(long numerator, long denominator)&nbsp; {&nbsp; &nbsp; this(BigInteger.valueOf(numerator), BigInteger.valueOf(denominator));&nbsp; }&nbsp; public BigFraction(long numerator)&nbsp; {&nbsp; &nbsp; this(BigInteger.valueOf(numerator), BigInteger.ONE, true);&nbsp; }&nbsp; /**&nbsp; &nbsp;* Constructs a BigFraction from a floating-point number.&nbsp; &nbsp;*&nbsp;&nbsp; &nbsp;* Warning: round-off error in IEEE floating point numbers can result&nbsp; &nbsp;* in answers that are unexpected.&nbsp; For example,&nbsp;&nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;System.out.println(new BigFraction(1.1))&nbsp; &nbsp;* will print:&nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;2476979795053773/2251799813685248&nbsp; &nbsp;*&nbsp;&nbsp; &nbsp;* This is because 1.1 cannot be expressed exactly in binary form.&nbsp; The&nbsp; &nbsp;* given fraction is exactly equal to the internal representation of&nbsp; &nbsp;* the double-precision floating-point number.&nbsp; (Which, for 1.1, is:&nbsp; &nbsp;* (-1)^0 * 2^0 * (1 + 0x199999999999aL / 0x10000000000000L).)&nbsp; &nbsp;*&nbsp;&nbsp; &nbsp;* NOTE: In many cases, BigFraction(Double.toString(d)) may give a result&nbsp; &nbsp;* closer to what the user expects.&nbsp; &nbsp;*/&nbsp; public BigFraction(double d)&nbsp; {&nbsp; &nbsp; if(Double.isInfinite(d))&nbsp; &nbsp; &nbsp; throw new IllegalArgumentException("double val is infinite");&nbsp; &nbsp; if(Double.isNaN(d))&nbsp; &nbsp; &nbsp; throw new IllegalArgumentException("double val is NaN");&nbsp; &nbsp; //special case - math below won't work right for 0.0 or -0.0&nbsp; &nbsp; if(d == 0)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; numerator = BigInteger.ZERO;&nbsp; &nbsp; &nbsp; denominator = BigInteger.ONE;&nbsp; &nbsp; &nbsp; return;&nbsp; &nbsp; }&nbsp; &nbsp; final long bits = Double.doubleToLongBits(d);&nbsp; &nbsp; final int sign = (int)(bits >> 63) & 0x1;&nbsp; &nbsp; final int exponent = ((int)(bits >> 52) & 0x7ff) - 0x3ff;&nbsp; &nbsp; final long mantissa = bits & 0xfffffffffffffL;&nbsp; &nbsp; //number is (-1)^sign * 2^(exponent) * 1.mantissa&nbsp; &nbsp; BigInteger tmpNumerator = BigInteger.valueOf(sign==0 ? 1 : -1);&nbsp; &nbsp; BigInteger tmpDenominator = BigInteger.ONE;&nbsp; &nbsp; //use shortcut: 2^x == 1 << x.&nbsp; if x is negative, shift the denominator&nbsp; &nbsp; if(exponent >= 0)&nbsp; &nbsp; &nbsp; tmpNumerator = tmpNumerator.multiply(BigInteger.ONE.shiftLeft(exponent));&nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; tmpDenominator = tmpDenominator.multiply(BigInteger.ONE.shiftLeft(-exponent));&nbsp; &nbsp; //1.mantissa == 1 + mantissa/2^52 == (2^52 + mantissa)/2^52&nbsp; &nbsp; tmpDenominator = tmpDenominator.multiply(BigInteger.valueOf(0x10000000000000L));&nbsp; &nbsp; tmpNumerator = tmpNumerator.multiply(BigInteger.valueOf(0x10000000000000L + mantissa));&nbsp; &nbsp; BigInteger gcd = tmpNumerator.gcd(tmpDenominator);&nbsp; &nbsp; numerator = tmpNumerator.divide(gcd);&nbsp; &nbsp; denominator = tmpDenominator.divide(gcd);&nbsp; }&nbsp; /**&nbsp; &nbsp;* Constructs a BigFraction from two floating-point numbers.&nbsp; &nbsp;*&nbsp;&nbsp; &nbsp;* Warning: round-off error in IEEE floating point numbers can result&nbsp; &nbsp;* in answers that are unexpected.&nbsp; See BigFraction(double) for more&nbsp; &nbsp;* information.&nbsp; &nbsp;*&nbsp;&nbsp; &nbsp;* NOTE: In many cases, BigFraction(Double.toString(numerator) + "/" + Double.toString(denominator))&nbsp; &nbsp;* may give a result closer to what the user expects.&nbsp; &nbsp;*/&nbsp; public BigFraction(double numerator, double denominator)&nbsp; {&nbsp; &nbsp; if(denominator == 0)&nbsp; &nbsp; &nbsp; throw new ArithmeticException("Divide by zero.");&nbsp; &nbsp; BigFraction tmp = new BigFraction(numerator).divide(new BigFraction(denominator));&nbsp; &nbsp; this.numerator = tmp.numerator;&nbsp; &nbsp; this.denominator = tmp.denominator;&nbsp; }&nbsp; /**&nbsp; &nbsp;* Constructs a new BigFraction from the given BigDecimal object.&nbsp; &nbsp;*/&nbsp; public BigFraction(BigDecimal d)&nbsp; {&nbsp; &nbsp; this(d.scale() < 0 ? d.unscaledValue().multiply(BigInteger.TEN.pow(-d.scale())) : d.unscaledValue(),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;d.scale() < 0 ? BigInteger.ONE&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: BigInteger.TEN.pow(d.scale()));&nbsp; }&nbsp; public BigFraction(BigDecimal numerator, BigDecimal denominator)&nbsp; {&nbsp; &nbsp; if(denominator.equals(BigDecimal.ZERO))&nbsp; &nbsp; &nbsp; throw new ArithmeticException("Divide by zero.");&nbsp; &nbsp; BigFraction tmp = new BigFraction(numerator).divide(new BigFraction(denominator));&nbsp; &nbsp; this.numerator = tmp.numerator;&nbsp; &nbsp; this.denominator = tmp.denominator;&nbsp; }&nbsp; /**&nbsp; &nbsp;* Constructs a BigFraction from a String.&nbsp; Expected format is numerator/denominator,&nbsp; &nbsp;* but /denominator part is optional.&nbsp; Either numerator or denominator may be a floating-&nbsp; &nbsp;* point decimal number, which in the same format as a parameter to the&nbsp; &nbsp;* <code>BigDecimal(String)</code> constructor.&nbsp; &nbsp;*&nbsp;&nbsp; &nbsp;* @throws NumberFormatException&nbsp; if the string cannot be properly parsed.&nbsp; &nbsp;*/&nbsp; public BigFraction(String s)&nbsp; {&nbsp; &nbsp; int slashPos = s.indexOf('/');&nbsp; &nbsp; if(slashPos < 0)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; BigFraction res = new BigFraction(new BigDecimal(s));&nbsp; &nbsp; &nbsp; this.numerator = res.numerator;&nbsp; &nbsp; &nbsp; this.denominator = res.denominator;&nbsp; &nbsp; }&nbsp; &nbsp; else&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; BigDecimal num = new BigDecimal(s.substring(0, slashPos));&nbsp; &nbsp; &nbsp; BigDecimal den = new BigDecimal(s.substring(slashPos+1, s.length()));&nbsp; &nbsp; &nbsp; BigFraction res = new BigFraction(num, den);&nbsp; &nbsp; &nbsp; this.numerator = res.numerator;&nbsp; &nbsp; &nbsp; this.denominator = res.denominator;&nbsp; &nbsp; }&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns this + f.&nbsp; &nbsp;*/&nbsp; public BigFraction add(BigFraction f)&nbsp; {&nbsp; &nbsp; if(f == null)&nbsp; &nbsp; &nbsp; throw new IllegalArgumentException("Null argument");&nbsp; &nbsp; //n1/d1 + n2/d2 = (n1*d2 + d1*n2)/(d1*d2)&nbsp;&nbsp; &nbsp; return new BigFraction(numerator.multiply(f.denominator).add(denominator.multiply(f.numerator)),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;denominator.multiply(f.denominator));&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns this + b.&nbsp; &nbsp;*/&nbsp; public BigFraction add(BigInteger b)&nbsp; {&nbsp; &nbsp; if(b == null)&nbsp; &nbsp; &nbsp; throw new IllegalArgumentException("Null argument");&nbsp; &nbsp; //n1/d1 + n2 = (n1 + d1*n2)/d1&nbsp; &nbsp; return new BigFraction(numerator.add(denominator.multiply(b)),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;denominator, true);&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns this + n.&nbsp; &nbsp;*/&nbsp; public BigFraction add(long n)&nbsp; {&nbsp; &nbsp; return add(BigInteger.valueOf(n));&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns this - f.&nbsp; &nbsp;*/&nbsp; public BigFraction subtract(BigFraction f)&nbsp; {&nbsp; &nbsp; if(f == null)&nbsp; &nbsp; &nbsp; throw new IllegalArgumentException("Null argument");&nbsp; &nbsp; return new BigFraction(numerator.multiply(f.denominator).subtract(denominator.multiply(f.numerator)),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;denominator.multiply(f.denominator));&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns this - b.&nbsp; &nbsp;*/&nbsp; public BigFraction subtract(BigInteger b)&nbsp; {&nbsp; &nbsp; if(b == null)&nbsp; &nbsp; &nbsp; throw new IllegalArgumentException("Null argument");&nbsp; &nbsp; return new BigFraction(numerator.subtract(denominator.multiply(b)),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;denominator, true);&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns this - n.&nbsp; &nbsp;*/&nbsp; public BigFraction subtract(long n)&nbsp; {&nbsp; &nbsp; return subtract(BigInteger.valueOf(n));&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns this * f.&nbsp; &nbsp;*/&nbsp; public BigFraction multiply(BigFraction f)&nbsp; {&nbsp; &nbsp; if(f == null)&nbsp; &nbsp; &nbsp; throw new IllegalArgumentException("Null argument");&nbsp; &nbsp; return new BigFraction(numerator.multiply(f.numerator), denominator.multiply(f.denominator));&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns this * b.&nbsp; &nbsp;*/&nbsp; public BigFraction multiply(BigInteger b)&nbsp; {&nbsp; &nbsp; if(b == null)&nbsp; &nbsp; &nbsp; throw new IllegalArgumentException("Null argument");&nbsp; &nbsp; return new BigFraction(numerator.multiply(b), denominator);&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns this * n.&nbsp; &nbsp;*/&nbsp; public BigFraction multiply(long n)&nbsp; {&nbsp; &nbsp; return multiply(BigInteger.valueOf(n));&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns this / f.&nbsp; &nbsp;*/&nbsp; public BigFraction divide(BigFraction f)&nbsp; {&nbsp; &nbsp; if(f == null)&nbsp; &nbsp; &nbsp; throw new IllegalArgumentException("Null argument");&nbsp; &nbsp; if(f.numerator.equals(BigInteger.ZERO))&nbsp; &nbsp; &nbsp; throw new ArithmeticException("Divide by zero");&nbsp; &nbsp; return new BigFraction(numerator.multiply(f.denominator), denominator.multiply(f.numerator));&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns this / b.&nbsp; &nbsp;*/&nbsp; public BigFraction divide(BigInteger b)&nbsp; {&nbsp; &nbsp; if(b == null)&nbsp; &nbsp; &nbsp; throw new IllegalArgumentException("Null argument");&nbsp; &nbsp; if(b.equals(BigInteger.ZERO))&nbsp; &nbsp; &nbsp; throw new ArithmeticException("Divide by zero");&nbsp; &nbsp; return new BigFraction(numerator, denominator.multiply(b));&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns this / n.&nbsp; &nbsp;*/&nbsp; public BigFraction divide(long n)&nbsp; {&nbsp; &nbsp; return divide(BigInteger.valueOf(n));&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns this^exponent.&nbsp; &nbsp;*/&nbsp; public BigFraction pow(int exponent)&nbsp; {&nbsp; &nbsp; if(exponent == 0)&nbsp; &nbsp; &nbsp; return BigFraction.ONE;&nbsp; &nbsp; else if (exponent == 1)&nbsp; &nbsp; &nbsp; return this;&nbsp; &nbsp; else if (exponent < 0)&nbsp; &nbsp; &nbsp; return new BigFraction(denominator.pow(-exponent), numerator.pow(-exponent), true);&nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; return new BigFraction(numerator.pow(exponent), denominator.pow(exponent), true);&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns 1/this.&nbsp; &nbsp;*/&nbsp; public BigFraction reciprocal()&nbsp; {&nbsp; &nbsp; if(this.numerator.equals(BigInteger.ZERO))&nbsp; &nbsp; &nbsp; throw new ArithmeticException("Divide by zero");&nbsp; &nbsp; return new BigFraction(denominator, numerator, true);&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns the complement of this fraction, which is equal to 1 - this.&nbsp; &nbsp;* Useful for probabilities/statistics.&nbsp; &nbsp;*/&nbsp; public BigFraction complement()&nbsp; {&nbsp; &nbsp; return new BigFraction(denominator.subtract(numerator), denominator, true);&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns -this.&nbsp; &nbsp;*/&nbsp; public BigFraction negate()&nbsp; {&nbsp; &nbsp; return new BigFraction(numerator.negate(), denominator, true);&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns -1, 0, or 1, representing the sign of this fraction.&nbsp; &nbsp;*/&nbsp; public int signum()&nbsp; {&nbsp; &nbsp; return numerator.signum();&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns the absolute value of this.&nbsp; &nbsp;*/&nbsp; public BigFraction abs()&nbsp; {&nbsp; &nbsp; return (signum() < 0 ? negate() : this);&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns a string representation of this, in the form&nbsp; &nbsp;* numerator/denominator.&nbsp; &nbsp;*/&nbsp; public String toString()&nbsp; {&nbsp; &nbsp; return numerator.toString() + "/" + denominator.toString();&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns if this object is equal to another object.&nbsp; &nbsp;*/&nbsp; public boolean equals(Object o)&nbsp; {&nbsp; &nbsp; if(!(o instanceof BigFraction))&nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; BigFraction f = (BigFraction)o;&nbsp; &nbsp; return numerator.equals(f.numerator) && denominator.equals(f.denominator);&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns a hash code for this object.&nbsp; &nbsp;*/&nbsp; public int hashCode()&nbsp; {&nbsp; &nbsp; //using the method generated by Eclipse, but streamlined a bit..&nbsp; &nbsp; return (31 + numerator.hashCode())*31 + denominator.hashCode();&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns a negative, zero, or positive number, indicating if this object&nbsp; &nbsp;* is less than, equal to, or greater than f, respectively.&nbsp; &nbsp;*/&nbsp; public int compareTo(BigFraction f)&nbsp; {&nbsp; &nbsp; if(f == null)&nbsp; &nbsp; &nbsp; throw new IllegalArgumentException("Null argument");&nbsp; &nbsp; //easy case: this and f have different signs&nbsp; &nbsp; if(signum() != f.signum())&nbsp; &nbsp; &nbsp; return signum() - f.signum();&nbsp; &nbsp; //next easy case: this and f have the same denominator&nbsp; &nbsp; if(denominator.equals(f.denominator))&nbsp; &nbsp; &nbsp; return numerator.compareTo(f.numerator);&nbsp; &nbsp; //not an easy case, so first make the denominators equal then compare the numerators&nbsp;&nbsp; &nbsp; return numerator.multiply(f.denominator).compareTo(denominator.multiply(f.numerator));&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns the smaller of this and f.&nbsp; &nbsp;*/&nbsp; public BigFraction min(BigFraction f)&nbsp; {&nbsp; &nbsp; if(f == null)&nbsp; &nbsp; &nbsp; throw new IllegalArgumentException("Null argument");&nbsp; &nbsp; return (this.compareTo(f) <= 0 ? this : f);&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns the maximum of this and f.&nbsp; &nbsp;*/&nbsp; public BigFraction max(BigFraction f)&nbsp; {&nbsp; &nbsp; if(f == null)&nbsp; &nbsp; &nbsp; throw new IllegalArgumentException("Null argument");&nbsp; &nbsp; return (this.compareTo(f) >= 0 ? this : f);&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns a positive BigFraction, greater than or equal to zero, and less than one.&nbsp; &nbsp;*/&nbsp; public static BigFraction random()&nbsp; {&nbsp; &nbsp; return new BigFraction(Math.random());&nbsp; }&nbsp; public final BigInteger getNumerator() { return numerator; }&nbsp; public final BigInteger getDenominator() { return denominator; }&nbsp; //implementation of Number class.&nbsp; may cause overflow.&nbsp; public byte&nbsp; &nbsp;byteValue()&nbsp; &nbsp;{ return (byte) Math.max(Byte.MIN_VALUE,&nbsp; &nbsp; Math.min(Byte.MAX_VALUE,&nbsp; &nbsp; longValue())); }&nbsp; public short&nbsp; shortValue()&nbsp; { return (short)Math.max(Short.MIN_VALUE,&nbsp; &nbsp;Math.min(Short.MAX_VALUE,&nbsp; &nbsp;longValue())); }&nbsp; public int&nbsp; &nbsp; intValue()&nbsp; &nbsp; { return (int)&nbsp; Math.max(Integer.MIN_VALUE, Math.min(Integer.MAX_VALUE, longValue())); }&nbsp; public long&nbsp; &nbsp;longValue()&nbsp; &nbsp;{ return Math.round(doubleValue()); }&nbsp; public float&nbsp; floatValue()&nbsp; { return (float)doubleValue(); }&nbsp; public double doubleValue() { return toBigDecimal(18).doubleValue(); }&nbsp; /**&nbsp; &nbsp;* Returns a BigDecimal representation of this fraction.&nbsp; If possible, the&nbsp; &nbsp;* returned value will be exactly equal to the fraction.&nbsp; If not, the BigDecimal&nbsp; &nbsp;* will have a scale large enough to hold the same number of significant figures&nbsp; &nbsp;* as both numerator and denominator, or the equivalent of a double-precision&nbsp; &nbsp;* number, whichever is more.&nbsp; &nbsp;*/&nbsp; public BigDecimal toBigDecimal()&nbsp; {&nbsp; &nbsp; //Implementation note:&nbsp; A fraction can be represented exactly in base-10 iff its&nbsp; &nbsp; //denominator is of the form 2^a * 5^b, where a and b are nonnegative integers.&nbsp; &nbsp; //(In other words, if there are no prime factors of the denominator except for&nbsp; &nbsp; //2 and 5, or if the denominator is 1).&nbsp; So to determine if this denominator is&nbsp; &nbsp; //of this form, continually divide by 2 to get the number of 2's, and then&nbsp; &nbsp; //continually divide by 5 to get the number of 5's.&nbsp; Afterward, if the denominator&nbsp; &nbsp; //is 1 then there are no other prime factors.&nbsp; &nbsp; //Note: number of 2's is given by the number of trailing 0 bits in the number&nbsp; &nbsp; int twos = denominator.getLowestSetBit();&nbsp; &nbsp; BigInteger tmpDen = denominator.shiftRight(twos); // x / 2^n === x >> n&nbsp; &nbsp; final BigInteger FIVE = BigInteger.valueOf(5);&nbsp; &nbsp; int fives = 0;&nbsp; &nbsp; BigInteger[] divMod = null;&nbsp; &nbsp; //while(tmpDen % 5 == 0) { fives++; tmpDen /= 5; }&nbsp; &nbsp; while(BigInteger.ZERO.equals((divMod = tmpDen.divideAndRemainder(FIVE))[1]))&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; fives++;&nbsp; &nbsp; &nbsp; tmpDen = divMod[0];&nbsp; &nbsp; }&nbsp; &nbsp; if(BigInteger.ONE.equals(tmpDen))&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; //This fraction will terminate in base 10, so it can be represented exactly as&nbsp; &nbsp; &nbsp; //a BigDecimal.&nbsp; We would now like to make the fraction of the form&nbsp; &nbsp; &nbsp; //unscaled / 10^scale.&nbsp; We know that 2^x * 5^x = 10^x, and our denominator is&nbsp; &nbsp; &nbsp; //in the form 2^twos * 5^fives.&nbsp; So use max(twos, fives) as the scale, and&nbsp; &nbsp; &nbsp; //multiply the numerator and deminator by the appropriate number of 2's or 5's&nbsp; &nbsp; &nbsp; //such that the denominator is of the form 2^scale * 5^scale.&nbsp; (Of course, we&nbsp; &nbsp; &nbsp; //only have to actually multiply the numerator, since all we need for the&nbsp; &nbsp; &nbsp; //BigDecimal constructor is the scale.&nbsp; &nbsp; &nbsp; BigInteger unscaled = numerator;&nbsp; &nbsp; &nbsp; int scale = Math.max(twos, fives);&nbsp; &nbsp; &nbsp; if(twos < fives)&nbsp; &nbsp; &nbsp; &nbsp; unscaled = unscaled.shiftLeft(fives - twos); //x * 2^n === x << n&nbsp; &nbsp; &nbsp; else if (fives < twos)&nbsp; &nbsp; &nbsp; &nbsp; unscaled = unscaled.multiply(FIVE.pow(twos - fives));&nbsp; &nbsp; &nbsp; return new BigDecimal(unscaled, scale);&nbsp; &nbsp; }&nbsp; &nbsp; //else: this number will repeat infinitely in base-10.&nbsp; So try to figure out&nbsp; &nbsp; //a good number of significant digits.&nbsp; Start with the number of digits required&nbsp; &nbsp; //to represent the numerator and denominator in base-10, which is given by&nbsp; &nbsp; //bitLength / log[2](10).&nbsp; (bitLenth is the number of digits in base-2).&nbsp; &nbsp; final double LG10 = 3.321928094887362; //Precomputed ln(10)/ln(2), a.k.a. log[2](10)&nbsp; &nbsp; int precision = Math.max(numerator.bitLength(), denominator.bitLength());&nbsp; &nbsp; precision = (int)Math.ceil(precision / LG10);&nbsp; &nbsp; //If the precision is less than 18 digits, use 18 digits so that the number&nbsp; &nbsp; //will be at least as accurate as a cast to a double.&nbsp; For example, with&nbsp; &nbsp; //the fraction 1/3, precision will be 1, giving a result of 0.3.&nbsp; This is&nbsp; &nbsp; //quite a bit different from what a user would expect.&nbsp; &nbsp; if(precision < 18)&nbsp; &nbsp; &nbsp; precision = 18;&nbsp; &nbsp; return toBigDecimal(precision);&nbsp; }&nbsp; /**&nbsp; &nbsp;* Returns a BigDecimal representation of this fraction, with a given precision.&nbsp; &nbsp;* @param precision&nbsp; the number of significant figures to be used in the result.&nbsp; &nbsp;*/&nbsp; public BigDecimal toBigDecimal(int precision)&nbsp; {&nbsp; &nbsp; return new BigDecimal(numerator).divide(new BigDecimal(denominator), new MathContext(precision, RoundingMode.HALF_EVEN));&nbsp; }&nbsp; //--------------------------------------------------------------------------&nbsp; //&nbsp; PRIVATE FUNCTIONS&nbsp; //--------------------------------------------------------------------------&nbsp; /**&nbsp; &nbsp;* Private constructor, used when you can be certain that the fraction is already in&nbsp; &nbsp;* lowest terms.&nbsp; No check is done to reduce numerator/denominator.&nbsp; A check is still&nbsp; &nbsp;* done to maintain a positive denominator.&nbsp; &nbsp;*&nbsp;&nbsp; &nbsp;* @param throwaway&nbsp; unused variable, only here to signal to the compiler that this&nbsp; &nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;constructor should be used.&nbsp; &nbsp;*/&nbsp; private BigFraction(BigInteger numerator, BigInteger denominator, boolean throwaway)&nbsp; {&nbsp; &nbsp; if(denominator.signum() < 0)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; this.numerator = numerator.negate();&nbsp; &nbsp; &nbsp; this.denominator = denominator.negate();&nbsp; &nbsp; }&nbsp; &nbsp; else&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; this.numerator = numerator;&nbsp; &nbsp; &nbsp; this.denominator = denominator;&nbsp; &nbsp; }&nbsp; }}

白衣染霜花

使它不变 ;使其规范,意味着6/4变为3/2(对此,最大的公约数算法很有用);称其为有理数,因为您所代表的是有理数;您可以BigInteger用来存储任意精度的值。如果不是那样的话long,那么实现起来会更容易;使分母始终为正。分子应带有符号。延伸Number;实施Comparable<T>;实施equals()和hashCode();为用表示的数字添加工厂方法String;添加一些便利的工厂方法;添加toString(); 和做吧Serializable。实际上,请尝试使用此尺寸。它可以运行,但可能存在一些问题:public class BigRational extends Number implements Comparable<BigRational>, Serializable {&nbsp; &nbsp; public final static BigRational ZERO = new BigRational(BigInteger.ZERO, BigInteger.ONE);&nbsp; &nbsp; private final static long serialVersionUID = 1099377265582986378L;&nbsp; &nbsp; private final BigInteger numerator, denominator;&nbsp; &nbsp; private BigRational(BigInteger numerator, BigInteger denominator) {&nbsp; &nbsp; &nbsp; &nbsp; this.numerator = numerator;&nbsp; &nbsp; &nbsp; &nbsp; this.denominator = denominator;&nbsp; &nbsp; }&nbsp; &nbsp; private static BigRational canonical(BigInteger numerator, BigInteger denominator, boolean checkGcd) {&nbsp; &nbsp; &nbsp; &nbsp; if (denominator.signum() == 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new IllegalArgumentException("denominator is zero");&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if (numerator.signum() == 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return ZERO;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if (denominator.signum() < 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; numerator = numerator.negate();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; denominator = denominator.negate();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if (checkGcd) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BigInteger gcd = numerator.gcd(denominator);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!gcd.equals(BigInteger.ONE)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; numerator = numerator.divide(gcd);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; denominator = denominator.divide(gcd);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return new BigRational(numerator, denominator);&nbsp; &nbsp; }&nbsp; &nbsp; public static BigRational getInstance(BigInteger numerator, BigInteger denominator) {&nbsp; &nbsp; &nbsp; &nbsp; return canonical(numerator, denominator, true);&nbsp; &nbsp; }&nbsp; &nbsp; public static BigRational getInstance(long numerator, long denominator) {&nbsp; &nbsp; &nbsp; &nbsp; return canonical(new BigInteger("" + numerator), new BigInteger("" + denominator), true);&nbsp; &nbsp; }&nbsp; &nbsp; public static BigRational getInstance(String numerator, String denominator) {&nbsp; &nbsp; &nbsp; &nbsp; return canonical(new BigInteger(numerator), new BigInteger(denominator), true);&nbsp; &nbsp; }&nbsp; &nbsp; public static BigRational valueOf(String s) {&nbsp; &nbsp; &nbsp; &nbsp; Pattern p = Pattern.compile("(-?\\d+)(?:.(\\d+)?)?0*(?:e(-?\\d+))?");&nbsp; &nbsp; &nbsp; &nbsp; Matcher m = p.matcher(s);&nbsp; &nbsp; &nbsp; &nbsp; if (!m.matches()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new IllegalArgumentException("Unknown format '" + s + "'");&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // this translates 23.123e5 to 25,123 / 1000 * 10^5 = 2,512,300 / 1 (GCD)&nbsp; &nbsp; &nbsp; &nbsp; String whole = m.group(1);&nbsp; &nbsp; &nbsp; &nbsp; String decimal = m.group(2);&nbsp; &nbsp; &nbsp; &nbsp; String exponent = m.group(3);&nbsp; &nbsp; &nbsp; &nbsp; String n = whole;&nbsp; &nbsp; &nbsp; &nbsp; // 23.123 => 23123&nbsp; &nbsp; &nbsp; &nbsp; if (decimal != null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; n += decimal;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; BigInteger numerator = new BigInteger(n);&nbsp; &nbsp; &nbsp; &nbsp; // exponent is an int because BigInteger.pow() takes an int argument&nbsp; &nbsp; &nbsp; &nbsp; // it gets more difficult if exponent needs to be outside {-2 billion,2 billion}&nbsp; &nbsp; &nbsp; &nbsp; int exp = exponent == null ? 0 : Integer.valueOf(exponent);&nbsp; &nbsp; &nbsp; &nbsp; int decimalPlaces = decimal == null ? 0 : decimal.length();&nbsp; &nbsp; &nbsp; &nbsp; exp -= decimalPlaces;&nbsp; &nbsp; &nbsp; &nbsp; BigInteger denominator;&nbsp; &nbsp; &nbsp; &nbsp; if (exp < 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; denominator = BigInteger.TEN.pow(-exp);&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; numerator = numerator.multiply(BigInteger.TEN.pow(exp));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; denominator = BigInteger.ONE;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // done&nbsp; &nbsp; &nbsp; &nbsp; return canonical(numerator, denominator, true);&nbsp; &nbsp; }&nbsp; &nbsp; // Comparable&nbsp; &nbsp; public int compareTo(BigRational o) {&nbsp; &nbsp; &nbsp; &nbsp; // note: this is a bit of cheat, relying on BigInteger.compareTo() returning&nbsp; &nbsp; &nbsp; &nbsp; // -1, 0 or 1.&nbsp; For the more general contract of compareTo(), you'd need to do&nbsp; &nbsp; &nbsp; &nbsp; // more checking&nbsp; &nbsp; &nbsp; &nbsp; if (numerator.signum() != o.numerator.signum()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return numerator.signum() - o.numerator.signum();&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // oddly BigInteger has gcd() but no lcm()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BigInteger i1 = numerator.multiply(o.denominator);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BigInteger i2 = o.numerator.multiply(denominator);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return i1.compareTo(i2); // expensive!&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; public BigRational add(BigRational o) {&nbsp; &nbsp; &nbsp; &nbsp; if (o.numerator.signum() == 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return this;&nbsp; &nbsp; &nbsp; &nbsp; } else if (numerator.signum() == 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return o;&nbsp; &nbsp; &nbsp; &nbsp; } else if (denominator.equals(o.denominator)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return new BigRational(numerator.add(o.numerator), denominator);&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return canonical(numerator.multiply(o.denominator).add(o.numerator.multiply(denominator)), denominator.multiply(o.denominator), true);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; public BigRational multiply(BigRational o) {&nbsp; &nbsp; &nbsp; &nbsp; if (numerator.signum() == 0 || o.numerator.signum( )== 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return ZERO;&nbsp; &nbsp; &nbsp; &nbsp; } else if (numerator.equals(o.denominator)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return canonical(o.numerator, denominator, true);&nbsp; &nbsp; &nbsp; &nbsp; } else if (o.numerator.equals(denominator)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return canonical(numerator, o.denominator, true);&nbsp; &nbsp; &nbsp; &nbsp; } else if (numerator.negate().equals(o.denominator)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return canonical(o.numerator.negate(), denominator, true);&nbsp; &nbsp; &nbsp; &nbsp; } else if (o.numerator.negate().equals(denominator)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return canonical(numerator.negate(), o.denominator, true);&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return canonical(numerator.multiply(o.numerator), denominator.multiply(o.denominator), true);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; public BigInteger getNumerator() { return numerator; }&nbsp; &nbsp; public BigInteger getDenominator() { return denominator; }&nbsp; &nbsp; public boolean isInteger() { return numerator.signum() == 0 || denominator.equals(BigInteger.ONE); }&nbsp; &nbsp; public BigRational negate() { return new BigRational(numerator.negate(), denominator); }&nbsp; &nbsp; public BigRational invert() { return canonical(denominator, numerator, false); }&nbsp; &nbsp; public BigRational abs() { return numerator.signum() < 0 ? negate() : this; }&nbsp; &nbsp; public BigRational pow(int exp) { return canonical(numerator.pow(exp), denominator.pow(exp), true); }&nbsp; &nbsp; public BigRational subtract(BigRational o) { return add(o.negate()); }&nbsp; &nbsp; public BigRational divide(BigRational o) { return multiply(o.invert()); }&nbsp; &nbsp; public BigRational min(BigRational o) { return compareTo(o) <= 0 ? this : o; }&nbsp; &nbsp; public BigRational max(BigRational o) { return compareTo(o) >= 0 ? this : o; }&nbsp; &nbsp; public BigDecimal toBigDecimal(int scale, RoundingMode roundingMode) {&nbsp; &nbsp; &nbsp; &nbsp; return isInteger() ? new BigDecimal(numerator) : new BigDecimal(numerator).divide(new BigDecimal(denominator), scale, roundingMode);&nbsp; &nbsp; }&nbsp; &nbsp; // Number&nbsp; &nbsp; public int intValue() { return isInteger() ? numerator.intValue() : numerator.divide(denominator).intValue(); }&nbsp; &nbsp; public long longValue() { return isInteger() ? numerator.longValue() : numerator.divide(denominator).longValue(); }&nbsp; &nbsp; public float floatValue() { return (float)doubleValue(); }&nbsp; &nbsp; public double doubleValue() { return isInteger() ? numerator.doubleValue() : numerator.doubleValue() / denominator.doubleValue(); }&nbsp; &nbsp; @Override&nbsp; &nbsp; public String toString() { return isInteger() ? String.format("%,d", numerator) : String.format("%,d / %,d", numerator, denominator); }&nbsp; &nbsp; @Override&nbsp; &nbsp; public boolean equals(Object o) {&nbsp; &nbsp; &nbsp; &nbsp; if (this == o) return true;&nbsp; &nbsp; &nbsp; &nbsp; if (o == null || getClass() != o.getClass()) return false;&nbsp; &nbsp; &nbsp; &nbsp; BigRational that = (BigRational) o;&nbsp; &nbsp; &nbsp; &nbsp; if (denominator != null ? !denominator.equals(that.denominator) : that.denominator != null) return false;&nbsp; &nbsp; &nbsp; &nbsp; if (numerator != null ? !numerator.equals(that.numerator) : that.numerator != null) return false;&nbsp; &nbsp; &nbsp; &nbsp; return true;&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public int hashCode() {&nbsp; &nbsp; &nbsp; &nbsp; int result = numerator != null ? numerator.hashCode() : 0;&nbsp; &nbsp; &nbsp; &nbsp; result = 31 * result + (denominator != null ? denominator.hashCode() : 0);&nbsp; &nbsp; &nbsp; &nbsp; return result;&nbsp; &nbsp; }&nbsp; &nbsp; public static void main(String args[]) {&nbsp; &nbsp; &nbsp; &nbsp; BigRational r1 = BigRational.valueOf("3.14e4");&nbsp; &nbsp; &nbsp; &nbsp; BigRational r2 = BigRational.getInstance(111, 7);&nbsp; &nbsp; &nbsp; &nbsp; dump("r1", r1);&nbsp; &nbsp; &nbsp; &nbsp; dump("r2", r2);&nbsp; &nbsp; &nbsp; &nbsp; dump("r1 + r2", r1.add(r2));&nbsp; &nbsp; &nbsp; &nbsp; dump("r1 - r2", r1.subtract(r2));&nbsp; &nbsp; &nbsp; &nbsp; dump("r1 * r2", r1.multiply(r2));&nbsp; &nbsp; &nbsp; &nbsp; dump("r1 / r2", r1.divide(r2));&nbsp; &nbsp; &nbsp; &nbsp; dump("r2 ^ 2", r2.pow(2));&nbsp; &nbsp; }&nbsp; &nbsp; public static void dump(String name, BigRational r) {&nbsp; &nbsp; &nbsp; &nbsp; System.out.printf("%s = %s%n", name, r);&nbsp; &nbsp; &nbsp; &nbsp; System.out.printf("%s.negate() = %s%n", name, r.negate());&nbsp; &nbsp; &nbsp; &nbsp; System.out.printf("%s.invert() = %s%n", name, r.invert());&nbsp; &nbsp; &nbsp; &nbsp; System.out.printf("%s.intValue() = %,d%n", name, r.intValue());&nbsp; &nbsp; &nbsp; &nbsp; System.out.printf("%s.longValue() = %,d%n", name, r.longValue());&nbsp; &nbsp; &nbsp; &nbsp; System.out.printf("%s.floatValue() = %,f%n", name, r.floatValue());&nbsp; &nbsp; &nbsp; &nbsp; System.out.printf("%s.doubleValue() = %,f%n", name, r.doubleValue());&nbsp; &nbsp; &nbsp; &nbsp; System.out.println();&nbsp; &nbsp; }}输出为:r1 = 31,400r1.negate() = -31,400r1.invert() = 1 / 31,400r1.intValue() = 31,400r1.longValue() = 31,400r1.floatValue() = 31,400.000000r1.doubleValue() = 31,400.000000r2 = 111 / 7r2.negate() = -111 / 7r2.invert() = 7 / 111r2.intValue() = 15r2.longValue() = 15r2.floatValue() = 15.857142r2.doubleValue() = 15.857143r1 + r2 = 219,911 / 7r1 + r2.negate() = -219,911 / 7r1 + r2.invert() = 7 / 219,911r1 + r2.intValue() = 31,415r1 + r2.longValue() = 31,415r1 + r2.floatValue() = 31,415.857422r1 + r2.doubleValue() = 31,415.857143r1 - r2 = 219,689 / 7r1 - r2.negate() = -219,689 / 7r1 - r2.invert() = 7 / 219,689r1 - r2.intValue() = 31,384r1 - r2.longValue() = 31,384r1 - r2.floatValue() = 31,384.142578r1 - r2.doubleValue() = 31,384.142857r1 * r2 = 3,485,400 / 7r1 * r2.negate() = -3,485,400 / 7r1 * r2.invert() = 7 / 3,485,400r1 * r2.intValue() = 497,914r1 * r2.longValue() = 497,914r1 * r2.floatValue() = 497,914.281250r1 * r2.doubleValue() = 497,914.285714r1 / r2 = 219,800 / 111r1 / r2.negate() = -219,800 / 111r1 / r2.invert() = 111 / 219,800r1 / r2.intValue() = 1,980r1 / r2.longValue() = 1,980r1 / r2.floatValue() = 1,980.180176r1 / r2.doubleValue() = 1,980.180180r2 ^ 2 = 12,321 / 49r2 ^ 2.negate() = -12,321 / 49r2 ^ 2.invert() = 49 / 12,321r2 ^ 2.intValue() = 251r2 ^ 2.longValue() = 251r2 ^ 2.floatValue() = 251.448975r2 ^ 2.doubleValue() = 251.448980

RISEBY

请使其成为一成不变的类型!小数的值不会改变-例如,一半不会变成三分之一。代替setDenominator,您可以使用withDenominator返回一个具有相同分子但指定分母的新分数。使用不可变类型,生活要容易得多。覆盖等号和哈希码也很明智,因此可以在地图和集合中使用。Outlaw Programmer关于算术运算符和字符串格式的观点也很好。作为一般指南,请看一下BigInteger和BigDecimal。他们没有做相同的事情,但是它们足够相似,可以给您带来好主意。
打开App,查看更多内容
随时随地看视频慕课网APP
我要回答