⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fraction.java

📁 Apache的common math数学软件包
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.commons.math.fraction;import java.math.BigInteger;import org.apache.commons.math.util.MathUtils;/** * Representation of a rational number. * * @since 1.1 * @version $Revision: 620373 $ $Date: 2008-02-10 18:18:39 -0700 (Sun, 10 Feb 2008) $ */public class Fraction extends Number implements Comparable {    /** A fraction representing "1 / 1". */    public static final Fraction ONE = new Fraction(1, 1);    /** A fraction representing "0 / 1". */    public static final Fraction ZERO = new Fraction(0, 1);    /** Serializable version identifier */    private static final long serialVersionUID = -8958519416450949235L;        /** The denominator. */    private final int denominator;        /** The numerator. */    private final int numerator;    /**     * Create a fraction given the double value.     * @param value the double value to convert to a fraction.     * @throws FractionConversionException if the continued fraction failed to     *         converge.     */    public Fraction(double value) throws FractionConversionException {        this(value, 1.0e-5, 100);    }    /**     * Create a fraction given the double value and maximum error allowed.     * <p>     * References:     * <ul>     * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html">     * Continued Fraction</a> equations (11) and (22)-(26)</li>     * </ul>     * </p>     * @param value the double value to convert to a fraction.     * @param epsilon maximum error allowed.  The resulting fraction is within     *        <code>epsilon</code> of <code>value</code>, in absolute terms.     * @param maxIterations maximum number of convergents     * @throws FractionConversionException if the continued fraction failed to     *         converge.     */    public Fraction(double value, double epsilon, int maxIterations)        throws FractionConversionException    {        this(value, epsilon, Integer.MAX_VALUE, maxIterations);    }    /**     * Create a fraction given the double value and maximum denominator.     * <p>     * References:     * <ul>     * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html">     * Continued Fraction</a> equations (11) and (22)-(26)</li>     * </ul>     * </p>     * @param value the double value to convert to a fraction.     * @param maxDenominator The maximum allowed value for denominator     * @throws FractionConversionException if the continued fraction failed to     *         converge     */    public Fraction(double value, int maxDenominator)        throws FractionConversionException    {       this(value, 0, maxDenominator, 100);    }    /**     * Create a fraction given the double value and either the maximum error     * allowed or the maximum number of denominator digits.     * <p>     *     * NOTE: This constructor is called with EITHER     *   - a valid epsilon value and the maxDenominator set to Integer.MAX_VALUE     *     (that way the maxDenominator has no effect).     * OR     *   - a valid maxDenominator value and the epsilon value set to zero     *     (that way epsilon only has effect if there is an exact match before     *     the maxDenominator value is reached).     * </p><p>     *     * It has been done this way so that the same code can be (re)used for both     * scenarios. However this could be confusing to users if it were part of     * the public API and this constructor should therefore remain PRIVATE.     * </p>     *     * See JIRA issue ticket MATH-181 for more details:     *     *     https://issues.apache.org/jira/browse/MATH-181     *     * @param value the double value to convert to a fraction.     * @param epsilon maximum error allowed.  The resulting fraction is within     *        <code>epsilon</code> of <code>value</code>, in absolute terms.     * @param maxDenominator maximum denominator value allowed.     * @param maxIterations maximum number of convergents     * @throws FractionConversionException if the continued fraction failed to     *         converge.     */    private Fraction(double value, double epsilon, int maxDenominator, int maxIterations)        throws FractionConversionException    {        long overflow = Integer.MAX_VALUE;        double r0 = value;        long a0 = (long)Math.floor(r0);        if (a0 > overflow) {            throw new FractionConversionException(value, a0, 1l);        }        // check for (almost) integer arguments, which should not go        // to iterations.        if (Math.abs(a0 - value) < epsilon) {            this.numerator = (int) a0;            this.denominator = 1;            return;        }       long p0 = 1;        long q0 = 0;        long p1 = a0;        long q1 = 1;        long p2 = 0;        long q2 = 1;        int n = 0;        boolean stop = false;        do {            ++n;            double r1 = 1.0 / (r0 - a0);            long a1 = (long)Math.floor(r1);            p2 = (a1 * p1) + p0;            q2 = (a1 * q1) + q0;            if ((p2 > overflow) || (q2 > overflow)) {                throw new FractionConversionException(value, p2, q2);            }                        double convergent = (double)p2 / (double)q2;            if (n < maxIterations && Math.abs(convergent - value) > epsilon && q2 < maxDenominator) {                p0 = p1;                p1 = p2;                q0 = q1;                q1 = q2;                a0 = a1;                r0 = r1;            } else {                stop = true;            }        } while (!stop);        if (n >= maxIterations) {            throw new FractionConversionException(value, maxIterations);        }                if (q2 < maxDenominator) {            this.numerator = (int) p2;            this.denominator = (int) q2;        } else {            this.numerator = (int) p1;            this.denominator = (int) q1;        }    }        /**     * Create a fraction given the numerator and denominator.  The fraction is     * reduced to lowest terms.     * @param num the numerator.     * @param den the denominator.     * @throws ArithmeticException if the denomiator is <code>zero</code>     */    public Fraction(int num, int den) {        super();        if (den == 0) {            throw new ArithmeticException("The denominator must not be zero");        }        if (den < 0) {            if (num == Integer.MIN_VALUE ||                    den == Integer.MIN_VALUE) {                throw new ArithmeticException("overflow: can't negate");            }            num = -num;            den = -den;        }        // reduce numerator and denominator by greatest common denominator.        int d = MathUtils.gcd(num, den);        if (d > 1) {            num /= d;            den /= d;        }                // move sign to numerator.        if (den < 0) {            num *= -1;            den *= -1;        }        this.numerator = num;        this.denominator = den;    }        /**     * Returns the absolute value of this fraction.     * @return the absolute value.     */    public Fraction abs() {        Fraction ret;        if (numerator >= 0) {            ret = this;        } else {            ret = negate();        }        return ret;            }        /**     * Compares this object to another based on size.     * @param object the object to compare to     * @return -1 if this is less than <tt>object</tt>, +1 if this is greater     *         than <tt>object</tt>, 0 if they are equal.     */    public int compareTo(Object object) {        int ret = 0;                if (this != object) {             Fraction other = (Fraction)object;            double first = doubleValue();            double second = other.doubleValue();                        if (first < second) {                ret = -1;            } else if (first > second) {                ret = 1;            }        }                return ret;    }        /**     * Gets the fraction as a <tt>double</tt>. This calculates the fraction as     * the numerator divided by denominator.     * @return the fraction as a <tt>double</tt>     */    public double doubleValue() {        return (double)numerator / (double)denominator;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -