Java课内-实验1:分数类(完全弹性碰撞)

Fraction.java

// Fraction.java
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.DecimalFormat;

/*
 * 分数类Fraction,形如 +a/b,可以进行加减乘除等运算。除了构造之外,内部数据不可更改
 */
public class Fraction implements Comparable<Fraction> {
    private int sign; //+1, 0, -1
    private BigInteger numerator; // 分子
    private BigInteger denominator; // 分母

    public static final Fraction ONE = new Fraction(1, 1); // 1/1
    public static final Fraction ZERO = new Fraction(0, 1);// 0/1
    public static final Fraction NaN = new Fraction(0, 0); // Not a Number
    public static final Fraction POSITIVE_INFINITY = new Fraction(1, 0); // 1/0, 表示正无穷
    public static final Fraction NEGATIVE_INFINITY = new Fraction(-1, 0); // -1/0,表示负无穷

    public Fraction() { // 默认构造函数,即ONE
        sign = 1;
        numerator = BigInteger.ONE;
        denominator = BigInteger.ONE;
    }
    public int getSign() {
        return sign;
    }
    public BigInteger getNumerator() {
        return numerator;
    }
    public BigInteger getDenominator() {
        return denominator;
    }
    /*
     * 最重要的构造方法。只输入分子分母两个参数,但不一定是最终的分子分母。
     * 构造过程中要实现约分为最简式!调用BigInteger类的gcd()方法。
     * 要处理特殊情况:
     * 如果是负无穷,负数/0,则最终为-1/0;
     * 如果是正无穷,正数/0,最终为+1/0;
     * 如果是 0/任何非零数,最终为0/1;
     * 如果是0/0,则最终为0/0,即NaN。
     */
    public Fraction(BigInteger bNumerator, BigInteger bDenominator) {
        // 在这里添加你自己的代码。
        //处理特殊情况:
        //分母为0
        if (bDenominator.equals(BigInteger.ZERO)){
            //1.如果是负无穷,负数/0,则最终为-1/0;
            if(bNumerator.compareTo(BigInteger.ZERO)<0){
                this.sign=-1;
                this.numerator= BigInteger.ONE;
                this.denominator=BigInteger.ZERO;
            }
            //2.如果是正无穷,正数/0,最终为+1/0;
             else if (bNumerator.compareTo(BigInteger.ZERO)>0){
                this.sign=1;
                this.numerator= BigInteger.ONE;
                this.denominator=BigInteger.ZERO;
            }else{
                //3.如果是0/0,则最终为0/0,即NaN。
                this.sign=0;
                this.numerator= BigInteger.ZERO;
                this.denominator=BigInteger.ZERO;
            }
        }else if (bNumerator.equals(BigInteger.ZERO)){
            //4.分母不为0,如果是 0/任何非零数,最终为0/1;
            this.sign=0;
            this.numerator=BigInteger.ZERO;
            this.denominator= BigInteger.ONE;
        }else {
            //其他情况:
            // 计算最大公约数
            BigInteger gcd = bNumerator.gcd(bDenominator);
            // 约分
            this.numerator = bNumerator.divide(gcd);
            this.denominator = bDenominator.divide(gcd);
            //默认符号为正
            sign=1;
            // 确保分子分母为正数
            if(this.numerator.compareTo(BigInteger.ZERO)<0){
                numerator=numerator.negate();
                sign=-sign;
            }
            if(this.denominator.compareTo(BigInteger.ZERO)<0){
                denominator=denominator.negate();
                sign=-sign;
            }
        }
    }
    public Fraction(long lNumerator, long lDenominator) { // 长整型构造方法
        this(new BigInteger("" + lNumerator), new BigInteger("" + lDenominator));
    }
    public Fraction(String sNumerator, String sDenominator) { // 字符串型构造方法
        this(new BigInteger(sNumerator), new BigInteger(sDenominator));
    }
    /*
     * 这是继承自Object的方法,返回描述对象的字符串,形如 +-a/b;
     * 如果是非数,则返回“NaN”;
     * 如果是正无穷,则返回“+inf”;
     * 如果是负无穷,则返回“-inf”;
     * 如果是零,则返回“0/1”;
     */
    @Override
    public String toString() {
        // 在这里添加你自己的代码。
        //处理特殊情况:
        if(numerator.equals(BigInteger.ZERO)&&denominator.equals(BigInteger.ZERO)){
            //非数:0/0,返回NaN
            return "NaN";
        }else if (denominator.equals(BigInteger.ZERO)) {
            // 分母为零,根据符号返回正无穷或负无穷
            return (sign == 1) ? "+inf" : "-inf";
        }else if (numerator.equals(BigInteger.ZERO)&&denominator.equals(BigInteger.ONE)){
            //0/1,零
            return  "0/1";
        }
        //其他情况:
        StringBuilder sb=new StringBuilder();
        if (sign==1)
            sb.append('+');
        else if (sign == -1) {//注意此处不为else,还要考虑sign为0,为0时不做处理
            sb.append('-');
        }
        sb.append(numerator).append('/').append(denominator);
        return sb.toString();

    }
    /*
     * 继承自Object的方法,返回一个内容与自身完全一样的对象。
     * 虽然返回类型为Object,但本质类型是 Fraction。
     */
    @Override
    public Object clone() {
        // 在这里添加你自己的代码。
        return new Fraction(this.sign==1? numerator:numerator.negate(),this.denominator);
    }
    @Override
    public int hashCode() { // 继承自Object的方法,计算哈希值。
        return sign + numerator.hashCode() + denominator.hashCode();
    }
    @Override
    public boolean equals(Object obj) { // 注意和compareTo有一点点冲突,权宜之计。
        Fraction that = (Fraction)obj;
        return this.sign == that.sign  &&  this.numerator.equals(that.numerator)  &&  this.denominator.equals(that.denominator);
    }
    /*
     * 实现接口Comparable,比较本对象和对象that的大小,返回-1,0,1三种值。
     * 设定正无穷和正无穷相等,负无穷和负无穷相等。
     * 设定ZERO和NaN相等(权宜之计)。
     */
    @Override
    public int compareTo(Fraction that) {
        // 在这里添加你自己的代码。
        if(this.sign>that.sign)
            return 1;
        else if (this.sign<that.sign)
            return -1;
        else {
            //处理特殊情况:
            //正无穷和正无穷相等,负无穷和负无穷相等
            if ((this.isPositiveInfinity()&&that.isPositiveInfinity())||this.isNegativeInfinity()&&that.isNegativeInfinity())
                return 0;
                //ZERO和NaN相等
            else if((this.numerator.equals(BigInteger.ZERO)&&this.denominator.equals(BigInteger.ONE))&&that.numerator.equals(BigInteger.ZERO)&&that.denominator.equals(BigInteger.ZERO))
                return 0;
            else if((that.numerator.equals(BigInteger.ZERO)&&that.denominator.equals(BigInteger.ONE))&&this.numerator.equals(BigInteger.ZERO)&&this.denominator.equals(BigInteger.ZERO))
                return 0;
            else if (this.isPositiveInfinity()||that.isNegativeInfinity()) {//正无穷大于其他任何数,负无穷小于其他任何数
                return 1;
            } else if (this.isNegativeInfinity()||that.isPositiveInfinity()) {
                return -1;
            }
            //其他一般情况
            BigInteger thisVal = this.numerator.multiply(that.denominator);
            BigInteger thatVal = that.numerator.multiply(this.denominator);
            return thisVal.compareTo(thatVal);

        }
    }
    public boolean isZero() {
        return equals(ZERO);
    }
    public boolean isOne() {
        return equals(ONE);
    }
    public boolean isNaN() {
        return equals(NaN);
    }
    public boolean isPositive() {
        return (sign > 0);
    }
    public boolean isNegative() {
        return (sign < 0);
    }
    public boolean isPositiveInfinity() {
        return equals(POSITIVE_INFINITY);
    }
    public boolean isNegativeInfinity() {
        return equals(NEGATIVE_INFINITY);
    }
    public boolean isInfinity() {
        return isPositiveInfinity() || isNegativeInfinity();
    }
    public Fraction abs() { // 返回另一个Fraction对象,是本对象的绝对值。
        // 在这里添加你自己的代码。
//        if (sign==-1)
//            return new Fraction(this.numerator.negate(),this.denominator);
        return new Fraction(this.numerator,this.denominator);
    }
    public Fraction negate() { // 返回本对象的相反数。
        // 在这里添加你自己的代码。
        //return new Fraction(this.numerator.negate(),this.denominator);
        //如果原数为正,则相反数应该为负,传入一个负的参数
        if (sign==1)
            return new Fraction(this.numerator.negate(),this.denominator);
        else if (sign==0)
            return ZERO;
        else//如果原数为负,则相反数应该为正,直接传入原来的两个参数即可得到一个正的
            return new Fraction(this.numerator,this.denominator);
    }
    /*
     * 私有方法,类内使用,类外不能使用。
     * 如果this对象和that对象都是非ZERO、非NaN,则比较两个分数的大小;
     * 返回 -1,0, 1 三者之一。
     */
    private int positiveCompareTo(Fraction that) {
        // 在这里添加你自己的代码。
        if(this.sign>that.sign)
            return 1;
        else if (this.sign<that.sign)
            return -1;
        else {
            //处理特殊情况:
            //正无穷和正无穷相等,负无穷和负无穷相等
            if (this.denominator.equals(BigInteger.ZERO)&&that.denominator.equals(BigInteger.ZERO))
                return 0;
                //处理ZERO和NaN
            else if((this.numerator.equals(BigInteger.ZERO)&&this.denominator.equals(BigInteger.ONE))&&that.numerator.equals(BigInteger.ZERO)&&that.denominator.equals(BigInteger.ZERO))
                return 0;
            else if((that.numerator.equals(BigInteger.ZERO)&&that.denominator.equals(BigInteger.ONE))&&this.numerator.equals(BigInteger.ZERO)&&this.denominator.equals(BigInteger.ZERO))
                return 0;
            else {
                //其他一般情况
                BigInteger thisVal = this.numerator.multiply(that.denominator);
                BigInteger thatVal = that.numerator.multiply(this.denominator);
                return thisVal.compareTo(thatVal);
            }
        }
    }
    /*
     * 私有方法,类内使用,类外不能使用。
     * 如果this和that对象非ZERO,非NaN,则计算其正值部分的和,也就是返回二者绝对值之和,也是一个分数。
     */
    private Fraction positiveAdd(Fraction that) {
        // 在这里添加你自己的代码。
        //排除特殊情况
        if (this.isZero()|| that.isZero()||this.isNaN()|| that.isNaN())
            return null;
        BigInteger newNumerator = this.numerator.multiply(that.denominator).add(that.numerator.multiply(this.denominator));
        BigInteger newDenominator = this.denominator.multiply(that.denominator);
        return new Fraction(newNumerator, newDenominator);
    }
    /*
     * 私有方法,类内使用,类外不能使用。
     * 两个分数的绝对值相减:abs(this)-abs(that)。
     * 注意结果有可能正分数,有可能是负分数。
     */
    private Fraction positiveSubtract(Fraction that) {
        // 在这里添加你自己的代码。
        BigInteger newNumerator = this.numerator.multiply(that.denominator).subtract(that.numerator.multiply(this.denominator));
        BigInteger newDenominator = this.denominator.multiply(that.denominator);
        return new Fraction(newNumerator, newDenominator);
    }
    /*
     * 两个分数相加,注意各种复杂情况的判断:
     * 正无穷和负无穷相加为NaN;
     * NaN与任何数相加都是NaN;
     */
    public Fraction add(Fraction that) {
        // 在这里添加你自己的代码。
        //处理特殊情况:
        // 处理 NaN 的情况
        if (this.isNaN() || that.isNaN()) {
            return NaN;
        }
        // 处理无穷大的情况
        if (this.isInfinity() && that.isInfinity()) {
            // 如果两个无穷大的符号相同,则返回当前无穷大
            if (this.sign == that.sign) {
                return this;
            } else {
                // 如果符号不同,则结果为 NaN
                return NaN;
            }
        }
        // 如果当前分数是无穷大,则返回当前分数
        if (this.isInfinity()) {
            return this;
        }
        // 如果另一个分数是无穷大,则返回另一个分数
        if (that.isInfinity()) {
            return that;
        }
        //0+x=x;
        if (this.isZero())
            return that;
        if (that.isZero())
            return this;

        // 处理一般情况:
        // 1.异号分数相加
        if(this.sign!=that.sign){
            //异号相加实际上是减法
            Fraction absThis = this.abs();
            Fraction absThat = that.abs();
            if (absThis.equals(absThat)) {
                // 如果绝对值相等,则结果为 0
                return ZERO;
            } else if (absThis.compareTo(absThat) > 0) {
                // 如果当前分数的绝对值更大,结果为this-that,且结果符号与this相同,
                BigInteger newNumerator = this.numerator.multiply(that.denominator).subtract(that.numerator.multiply(this.denominator));
                BigInteger newDenominator = this.denominator.multiply(that.denominator);
                int newSign=this.sign;
                Fraction result = new Fraction(newSign==1?newNumerator:newNumerator.negate(),newDenominator);
                return result;
            } else {
                // 同理,如果当前分数的绝对值小,结果为that-this,且结果符号与that相同,
                BigInteger newNumerator = that.numerator.multiply(this.denominator).subtract(this.numerator.multiply(that.denominator));
                BigInteger newDenominator = this.denominator.multiply(that.denominator);
                int newSign=that.sign;
                Fraction result = new Fraction(newSign==1?newNumerator:newNumerator.negate(),newDenominator);
                return result;
            }
        }
        //2.同号分数相加
        BigInteger newNumerator = this.numerator.multiply(that.denominator).add(that.numerator.multiply(this.denominator));
        BigInteger newDenominator = this.denominator.multiply(that.denominator);

        //注意处理同为负号:
        return new Fraction(this.sign==1? newNumerator:newNumerator.negate(), newDenominator);
    }
    public Fraction subtract(Fraction that) { // 两个分数相减:
        return add(that.negate());
    }
    private Fraction positiveMultiply(Fraction that) { //两个非零非NaN的分数的绝对值相乘
        // 在这里添加你自己的代码。
        BigInteger newNumerator = this.numerator.multiply(that.numerator);
        BigInteger newDenominator = this.denominator.multiply(that.denominator);
        return new Fraction(newNumerator, newDenominator);
    }
    private Fraction positiveDivide(Fraction that) { //两个非零非NaN的分数的绝对值相除
        // 在这里添加你自己的代码。
        BigInteger newNumerator = this.numerator.multiply(that.denominator);
        BigInteger newDenominator = this.denominator.multiply(that.numerator);
        return new Fraction(newNumerator, newDenominator);
    }
    /*
     * 本分数扩大ratio倍并返回新分数对象。
     * 如果本分数是NaN,则返回NaN;
     * 如果ratio是0:如果本分数是无穷,则返回NaN;如果不是无穷,则返回ZERO;
     * 除此之外,非特殊运算要考虑到ratio的正负号。
     */
    public Fraction enlarge(long ratio) {
        // 在这里添加你自己的代码。;
        //处理特殊情况
        if (this.isNaN())
            return NaN;
        if (ratio==0){
            if (this.isInfinity())
                return NaN;
            else
                return ZERO;
        }
        //一般情况:
        // 新符号由当前符号和ratio符号决定
        int newSign = this.sign * Long.signum(ratio);
        BigInteger newNumerator = this.numerator.multiply(BigInteger.valueOf(Math.abs(ratio)));

        Fraction result = new Fraction(newSign == 1 ? newNumerator : newNumerator.negate(), denominator);

        return result;
    }
    /*
     * 把本分数缩小ratio倍,并返回新的分数对象。
     * 如果本分数是NaN,则返回NaN;
     * 如果ratio是0,则:
     * (1)如果本分数是负无穷,则返回负无穷;
     * (2)如果本分数是正无穷,则返回正无穷;
     * (3)如果本分数是ZERO,则返回NaN;
     * (4)如果本分数是正数,则返回正无穷;
     * (5)如果本分数是负数,则返回负无穷。
     * 除此之外,非特殊运算时需要考虑ratio的正负号。
     */
    public Fraction diminish(long ratio) {
        // 在这里添加你自己的代码。
        //处理特殊情况:
        if (this.isNaN())
            return NaN;
        if (ratio==0){
            if (this.isInfinity())
                return this;
            else if (this.isZero())
                return NaN;
            else if (this.sign==1)
                return POSITIVE_INFINITY;
            else
                return NEGATIVE_INFINITY;
        }
        //一般情况:同上,缩小ratio倍即为分母扩大ratio倍
        // 新符号由当前符号和ratio符号决定
        int newSign = this.sign * Long.signum(ratio);
        BigInteger newDenominator = this.denominator.multiply(BigInteger.valueOf(Math.abs(ratio)));

        Fraction result = new Fraction(this.numerator, (newSign == 1 ? newDenominator : newDenominator.negate()));

        return result;
    }
    /*
     * 两分数相乘,注意各种复杂情况的判断:
     * NaN与任何数相乘都是NaN;
     * 正无穷与ZERO相乘为NaN;
     * 负无穷与ZERO相乘为NaN。
     */
    public Fraction multiply(Fraction that) {
        // 在这里添加你自己的代码。
        //处理特殊情况
        if (this.isNaN()||that.isNaN())
            return NaN;
        else if (this.isZero() && that.isInfinity() || this.isInfinity() && that.isZero())
            return NaN;
        else if (this.isInfinity() || that.isInfinity()) {
            return new Fraction(this.sign * that.sign, 0);
        }
        //一般情况:
        int newSign = this.sign * that.sign; // 符号由两个分数的符号决定
        Fraction result = this.positiveMultiply(that); // 计算绝对值的乘积
        return new Fraction(newSign == 1 ? result.numerator : result.numerator.negate(), result.denominator);
    }
    /*
     * 求本分数对象的倒数:
     * 正负无穷的倒数是ZERO;
     * ZERO的倒数是NaN;
     * NaN的倒数是NaN。
     */
    public Fraction reciprocal() {
        // 在这里添加你自己的代码。
        //TODO:这里应该是倒数而非是相反数,按倒数实现
        //处理特殊情况:
        if (this.isInfinity())
            return ZERO;
        else if (this.isZero()||this.isNaN())
            return NaN;

        //一般情况:
        return new Fraction((this.sign==1?this.denominator:this.denominator.negate()), this.numerator);
    }
    /*
     * 两数相除,注意复杂情况:
     * NaN做被除数和除数的结果都是NaN;
     * ZERO / ZERO的结果是NaN,ZERO/非ZERO非NaN的结果是ZERO;
     * 正数除以ZERO的结果是正无穷;负数除以ZERO的结果是负无穷;
     * 正负无穷除以正负无穷的结果是NaN。
     */
    public Fraction divide(Fraction that) {
        // 在这里添加你自己的代码。
        //特殊情况:
        if (this.isNaN()||that.isNaN())
            return NaN;
        else if (this.isZero()){
            if (that.isZero())
                return NaN;
            else
                return ZERO;
        }else if (that.isZero()){
            return this.compareTo(ZERO)>0? POSITIVE_INFINITY:NEGATIVE_INFINITY;
        }else  if (this.isInfinity()&&that.isInfinity()) {
            return NaN;
        }else if (that.isInfinity())
            return ZERO;
        //一般情况:除以一个分数等于乘他的倒数
        return this.multiply(that.reciprocal());
    }

    /*
     * 静态方法估算两个正的大整数的比值。
     * positiveLarger >= positiveSmaller
     * 返回的形式是:5.3208E2025,意义是,大正数是小正数的5.3208 * 10^2025 倍:
     */
    private static String estimateRatio(BigInteger positiveLarger, BigInteger positiveSmaller) {
//        // 在这里添加你自己的代码。
//        //使用自带科学计数法的BigDecimal
//        BigDecimal large = new BigDecimal(positiveLarger);
//        BigDecimal small = new BigDecimal(positiveSmaller);
//
//
//        BigDecimal ratio = large.divide(small,10, java.math.RoundingMode.HALF_UP);
//
//        // 使用 DecimalFormat 以科学计数法格式化比值:保留12位小数
//        DecimalFormat scientificFormat = new DecimalFormat("0.############E0");
//        String result = scientificFormat.format(ratio);
//
////        System.out.println(ratio);
////        System.out.println(result);
//
//        return result;


        StringBuilder result = new StringBuilder();
        BigInteger quotient = positiveLarger.divide(positiveSmaller);
        result.append(quotient.toString());

        BigInteger remainder = positiveLarger.mod(positiveSmaller);
        if (!remainder.equals(BigInteger.ZERO)) {
            result.append(".");
            int precision = 15; // 设定小数精度
            for (int i = 0; i < precision; i++) {
                remainder = remainder.multiply(BigInteger.TEN);
                quotient = remainder.divide(positiveSmaller);
                result.append(quotient.toString());
                remainder = remainder.mod(positiveSmaller);
                if (remainder.equals(BigInteger.ZERO)) {
                    break;
                }
            }
        }

        double ratio = Double.parseDouble(result.toString());

        // 转换为科学计数法
        int exponent = 0;
        if (ratio >= 10) {
            while (ratio >= 10) {
                ratio /= 10;
                exponent++;
            }
        } else if (ratio < 1) {
            while (ratio < 1) {
                ratio *= 10;
                exponent--;
            }
        }

        String str = String.format("%.12fE%d", ratio, exponent);


        //System.out.println(str);

        return str;
    }
    /*
     * 因为分数对象的分子和分母会很大,这里给出估计,以字符串的形式给出。
     * 特殊情况:正无穷返回“+inf”;负无穷返回“-inf”;NaN返回“NaN“。
     * 一般情况:返回 -5.3208E2025;(2030d)/(5d) 的形式,表示分子是分母的-5.3208E2025倍,分子有2030十进制位,分母有5位;
     * 或者返回 1/(-5.3208E2025);(5d)/(2030d) 的形式,表示分母是分子的-5.3208E2025倍,分子有5十进制位,分母有2030位。
     */
    public String estimate() {
        // 在这里添加你自己的代码。
        //特殊情况
        if (isPositiveInfinity()) {
            return "+inf";
        } else if (isNegativeInfinity()) {
            return "-inf";
        } else if (isNaN()) {
            return "NaN";
        }else if (isZero())
            return "0.0E0";

        if (numerator.compareTo(denominator) >= 0) {
            String ratio = estimateRatio(numerator, denominator);
            return (sign==1?"":"-")+ ratio + "; (" + numerator.toString().length() + "d)/(" + denominator.toString().length() + "d)";
        } else {
            String ratio = estimateRatio(denominator, numerator);
            return (sign==1?"":"-")+ "1/(" + ratio + "); (" + numerator.toString().length() + "d)/(" + denominator.toString().length() + "d)";
        }
    }
    /*
     * 方幂运算,times是幂次,可正、可负、可零。因为底已经化简,本运算为了提高效率,要求分子分母单独计算。
     * NaN 的任何次方幂都是NaN;
     * ZERO 的0次和负次方幂都是NaN;ZERO的正整数次方幂都是ZERO;
     * ONE的任何次方幂都是ONE;
     * 负无穷的正偶次方幂是正无穷,负无穷的正奇次方幂是负无穷;
     * 负无穷的零次幂是ONE,负数次幂是ZERO;
     * 正无穷的零次幂是ONE,正数次幂为正无穷,负数次幂为零。
     */
    public Fraction power(int times) {
        // 在这里添加你自己的代码。
        if (isNaN()) {
            return NaN;
        } else if (isZero()) {
            if (times == 0 || times < 0) {
                return NaN;
            } else {
                return ZERO;
            }
        } else if (isOne()) {
            return ONE;
        } else if (isPositiveInfinity()) {
            if (times == 0) {
                return ONE;
            } else if (times > 0) {
                return POSITIVE_INFINITY;
            } else {
                return ZERO;
            }
        } else if (isNegativeInfinity()) {
            if (times == 0) {
                return ONE;
            } else if (times > 0) {
                if (times % 2 == 0) {
                    return POSITIVE_INFINITY;
                } else {
                    return NEGATIVE_INFINITY;
                }
            } else {
                return ZERO;
            }
        }

        //幂运算
        BigInteger newNumerator = numerator.pow(Math.abs(times));
        BigInteger newDenominator = denominator.pow(Math.abs(times));

        //处理负幂
        if (times < 0) {
            BigInteger temp = newNumerator;
            newNumerator = newDenominator;
            newDenominator = temp;
        }

        //偶次幂为正,奇次幂看本身
        int newSign = (times % 2 == 0) ? 1 : sign;

        return new Fraction(newSign == 1 ? newNumerator : newNumerator.negate(), newDenominator);
    }
    public static void testAll() {
        Fraction fraction = new Fraction();
        System.out.println("Default fraction: " + fraction);

        fraction = new Fraction(new BigInteger("1234567890123456789"), new BigInteger("-987654321"));
        System.out.println("new Fraction(1234567890123456789, -987654321):");
        System.out.println(fraction);

        fraction = new Fraction(-258, 369);
        System.out.println("new Fraction(-258, 369):");
        System.out.println(fraction);

        fraction = new Fraction(-258, 0);
        System.out.println("new Fraction(-258, 0): ");
        System.out.println(fraction);

        fraction = new Fraction(0, -10);
        System.out.println("new Fraction(0, -10): ");
        System.out.println(fraction);

        fraction = new Fraction(12, -15);
        System.out.println("new Fraction(12, -15): ");
        System.out.println(fraction);

        System.out.println("new Fraction(12, -15).negate(): ");
        System.out.println(fraction.negate());

        System.out.println("new Fraction(12, -15).reciprocal(): ");
        System.out.println(fraction.reciprocal());

        Fraction fa = NEGATIVE_INFINITY;
        Fraction fb = new Fraction(-5, 10);
        System.out.println("NEGATIVE_INFINITY ? Fraction(-5, 10):");
        System.out.println(fa.compareTo(fb));

        System.out.println("NEGATIVE_INFINITY ? NEGATIVE_INFINITY:");
        System.out.println(fa.compareTo(fa));

        System.out.println("NaN ? ZERO:");
        System.out.println(NaN.compareTo(ZERO));

        System.out.println("POSITIVE_INFINITY ? NEGATIVE_INFINITY:");
        System.out.println(POSITIVE_INFINITY.compareTo(fa));

        System.out.println("ZERO equals NaN? :");
        System.out.println(ZERO.equals(NaN));

        System.out.println("NEGATIVE_INFINITY equals NEGATIVE_INFINITY? :");
        System.out.println(NEGATIVE_INFINITY.equals(NEGATIVE_INFINITY));

        fa = new Fraction(-6, 8);
        fb = new Fraction(15, -20);
        System.out.println("-6/8  equals  15/-20?:");
        System.out.println(fa.equals(fb));

        fa = ONE.negate().enlarge(-10);
        System.out.println("ONE.negate().enlarge(-10):");
        System.out.println(fa);

        fa = NEGATIVE_INFINITY.enlarge(-10);
        System.out.println("NEGATIVE_INFINITY.enlarge(-10):");
        System.out.println(fa);

        fa = ONE.negate().diminish(0);
        System.out.println("ONE.negate().diminish(0):");
        System.out.println(fa);

        fa = new Fraction(1000, -1001);
        System.out.println("new Fraction(1000, -1001).negate():");
        System.out.println(fa.negate());

        System.out.println("new Fraction(1000, -1001).reciprocal():");
        System.out.println(fa.reciprocal());

        System.out.println("NEGATIVE_INFINITY.reciprocal():");
        System.out.println(NEGATIVE_INFINITY.reciprocal());

        System.out.println("ZERO.reciprocal():");
        System.out.println(ZERO.reciprocal());

        System.out.println("NaN.reciprocal():");
        System.out.println(NaN.reciprocal());

        fa = new Fraction(5, 10);
        fb = new Fraction(1, -2);
        System.out.println("5/10  +  1/-2:");
        System.out.println(fa.add(fb));

        System.out.println("POSITIVE_INFINITY  +  1/-2:");
        System.out.println(POSITIVE_INFINITY.add(fb));

        System.out.println("NEGATIVE_INFINITY  +  POSITIVE_INFINITY:");
        System.out.println(NEGATIVE_INFINITY.add(POSITIVE_INFINITY));

        fa = new Fraction(1, 2);
        fb = new Fraction(-2, 3);
        System.out.println("new Fraction(1, 2).positiveAdd(new Fraction(-2, 3)): ");
        System.out.println(fa.positiveAdd(fb));

        System.out.println("new Fraction(1, 2).positiveMultiply(new Fraction(-2, 3)): ");
        System.out.println(fa.positiveMultiply(fb));

        System.out.println("new Fraction(1, 2).positiveDivide(new Fraction(-2, 3)): ");
        System.out.println(fa.positiveDivide(fb));

        System.out.println("new Fraction(1, 2).multiply(new Fraction(-2, 3)): ");
        System.out.println(fa.multiply(fb));

        System.out.println("new Fraction(1, 2).divide(new Fraction(-2, 3)): ");
        System.out.println(fa.divide(fb));

        System.out.println("NEGATIVE_INFINITY  *  NEGATIVE_INFINITY:");
        System.out.println(NEGATIVE_INFINITY.multiply(NEGATIVE_INFINITY));

        System.out.println("NEGATIVE_INFINITY  *  ZERO:");
        System.out.println(NEGATIVE_INFINITY.multiply(ZERO));

        System.out.println("ONE / NEGATIVE_INFINITY");
        System.out.println(ONE.divide(NEGATIVE_INFINITY));

        System.out.println("NEGATIVE_INFINITY / NEGATIVE_INFINITY");
        System.out.println(NEGATIVE_INFINITY.divide(NEGATIVE_INFINITY));

        Fraction[] fractions = {ONE, POSITIVE_INFINITY, ZERO, NaN, ONE, NEGATIVE_INFINITY, new Fraction(6, -8), new Fraction(2, 1), NEGATIVE_INFINITY };
        java.util.Arrays.sort(fractions);
        System.out.println("sort {ONE, POSITIVE_INFINITY, ZERO, NaN, ONE, NEGATIVE_INFINITY, new Fraction(6, -8), new Fraction(2, 1), NEGATIVE_INFINITY }:");
        for (int i=0; i<fractions.length; i++)
            System.out.print("" + fractions[i] + ", ");
        System.out.println();

        String piece = "1234567890";
        String sLong = "";
        for (int i=0; i<20; i++)
            sLong += piece;
        fa = new Fraction(sLong, "-" + piece + "8");
        System.out.println("" + fa + ".estimate():");
        System.out.println(fa.estimate());

        fa = new Fraction(piece + "8", "-" + sLong);
        System.out.println("" + fa + ".estimate():");
        System.out.println(fa.estimate());
    }
    public static void main(String[] args) {
        testAll();
    }
}

Olympiad.java

import java.math.BigInteger;

// Olympiad.java
public class Olympiad {
// 1/1 + 1/3 + 1/6 + 1/10 + 1/15 + 1/21 + ……
// 1 (2) 3 (3) 6 (4) 10 (5) 15 (6) 21
// an = 1 + (2) + (3) + … + (n) = n(n+1)/2
// Sn = 1/a1 + 1/a2 + 1/a3 + …… + 1/an

// Sn = 2/(1*2) + 2/(2*3) + 2/(3*4) + ... + 2/(n(n+1))
//      = 2[1/1 - 1/2 + 1/2 - 1/3 + 1/3 - 1/4 + ... + 1/n - 1/(n+1)]
//      = 2[1/1 - 1/(n+1)] = 2n/(n+1)
// 本方法对于给定的规模n,计算上述数组的前n项和:
public static Fraction accumulateProductReciprocal(int n) {
    // 在这里添加你自己的代码。
    return new Fraction(BigInteger.valueOf(2*n),BigInteger.valueOf(n+1));
}
// 本方法对于给定的规模n,计算调和级数和:1/1 + 1/2 + 1/3 + ...... + 1/(n-1) + 1/n
public static Fraction accumulateHarmonicSeries(int n) {
    // 在这里添加你自己的代码。
    Fraction sum = Fraction.ZERO;//默认构造为1,此处需手动赋予0;
    for (int i = 1; i <= n; i++) {
        sum = sum.add(new Fraction(BigInteger.valueOf(1), BigInteger.valueOf(i)));
    }
    return sum;
}
// 本函数计算交错奇数的和,输入n为项数:
// 1/1 - 1/2 + 1/3 - 1/4 + 1/5 - ...... +-1/n
public static Fraction accumulateAlternatingSeries(int n) {
    // 在这里添加你自己的代码。
    Fraction sum = Fraction.ZERO;//默认构造为1,此处需手动赋予0;
    for (int i = 1; i <= n; i++) {
        if (i%2==1)
            sum = sum.add(new Fraction(BigInteger.valueOf(1), BigInteger.valueOf(i)));
        else
            sum=sum.subtract(new Fraction(BigInteger.valueOf(1), BigInteger.valueOf(i)));
    }
    return sum;
}
public static void main(String[] args) {
    int n = 2025;
    Fraction sum = accumulateProductReciprocal(n);
    System.out.println("2/1*2 + 2/2*3 + 2/3*4 + ... + 2/" + n + "*" + (n+1) + ":");
    System.out.println(sum);
    System.out.println();
    sum = accumulateHarmonicSeries(n);
    System.out.println("1/1 + 1/2 + 1/3 + 1/4 + ...... + 1/" + n + ":");
    System.out.println(sum);
    System.out.println("sum.estimate():");
    System.out.println(sum.estimate());
    System.out.println();
    sum = accumulateAlternatingSeries(n);
    System.out.println("1/1 - 1/2 + 1/3 - 1/4 + ...... +-1/" + n + ":");
    System.out.println(sum);
    System.out.println();
    System.out.println("sum.estimate():");
    System.out.println(sum.estimate());
}

}

Collision.java

import java.math.BigInteger;

// Collision.java
public class Collision {
/*
* 如果大方块的质量是小方块质量的k倍,小方块的碰撞前速度是currU,大方块碰撞前的速度是currV:
* 计算发生碰撞后大小方块各自的速度,并放在仅含两个分数对象的一维数组中,并输出。
* 一维数组的第一个元素是小方块的速度,第二个元素是大方块的速度。注意速度都带有正负号。
/ private static Fraction[] collideOnce(int k, Fraction currU, Fraction currV) { // 在这里添加你自己的代码。 //联立能量守恒、动量守恒、M=km三式可得: //u=[(1-k)currU + 2kcurrV]/(k+1) //v=[2currU + (k-1)*currV]/(k+1)

    Fraction[] results = new Fraction[2];
    results[0] = currU.enlarge(1 - k).add(currV.enlarge(2 * k)).diminish(k + 1);
    results[1] = currU.enlarge(2).add(currV.enlarge(k - 1)).diminish(k + 1);

    return results;
}

/*
 * 如果大方块质量是小方块的k倍,小方块开始静止,大方块从右边以速度-1撞向小方块,小方块左侧有墙:
 * 求总共发生撞击的次数,和大小方块大的收尾速度(有正负号)。
 * 次数、小方块的收尾速度、大方块的收尾速度都是一个分数对象,放在一个一维数组中返回。
 */
public static Fraction[] collideThorough(int k) {
    // 在这里添加你自己的代码。
    // 初始化小方块速度为 0,大方块速度为 -1
    Fraction currU = new Fraction(BigInteger.valueOf(0), BigInteger.valueOf(1));
    Fraction currV = new Fraction(BigInteger.valueOf(-1),BigInteger.valueOf(1));
    // 初始化碰撞次数为 0 注意:碰撞次数为小方块的碰撞次数,包括方块之间的碰撞和方块与墙壁之间的碰撞
    int collisionCount = 0;

    //模拟碰撞:
    //初始状态:一开始大方块向左运动,速度为-1,小方块禁止,
    //终止模拟:当currV为正(向右),且|currU|<=|currV|时,两个方块不再发生碰撞,此时如果currU<0,还将和墙壁碰撞一次
    while (true) {
        if(currV.compareTo(Fraction.ZERO)>0 && currU.abs().compareTo(currV.abs())<=0 ){
            //大小方块之间不在碰撞
            if (currU.isNegative())
                collisionCount++;
            break;
        }else {
            //方块间碰撞:
            Fraction[] newV = collideOnce(k, currU, currV);
            currU=newV[0];
            currV=newV[1];
            collisionCount++;

            //与墙壁碰撞
            if (currU.isNegative()){
                currU=currU.negate();
                collisionCount++;
            }
        }
        //调试用
        //System.out.println(collisionCount);
    }

    Fraction[] result = new Fraction[3];
    result[0] = new Fraction(collisionCount, 1);
    result[1] = currU;
    result[2] = currV;

    return result;
}
public static void main(String[] args) {
    if (args.length == 0) {
        System.out.println("There need one integer as the parameter.");
        return;
    }
    int k = 2;
    try {
        k = Integer.parseInt(args[0]);
    } catch(NumberFormatException nfe) {
        System.out.println("The first parameter must be an integer.");
        return;
    }
    Fraction[] terminal = collideThorough(k);
    System.out.println("Total collision times: ");
    System.out.println(terminal[0].getNumerator());
    System.out.println();
    System.out.println("Terminal velocity of the smaller cube:");
    System.out.println("" + terminal[1] + " ## " + terminal[1].estimate());
    System.out.println();
    System.out.println("Terminal velocity of the larger cube:");
    System.out.println("" + terminal[2] + " ## " + terminal[2].estimate());
    System.out.println();
}

}

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇