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();
}
}