分数也称作有理数,两个分数四则运算的结果仍然是分数
不希望看到 1/6 + 1/6 的结果是分数的近似值 0.333,而是1/3
有理数有两个重要的成员:分子和分母,还有重要的四则运算
自定义Rational类实现对有理数的封装,Rational类的UML图如下
/**
* 自定义有理数类 Rational
*/
public class Rational {
// 赋初值,保证分母不为零,分数值为零
private int numerator = 0; // 分子
private int denominator = 1; // 分母
/**
* 设置分数的分子、分母
* 保证操作数、运算结果均为最简分数,最大公约数
*
* @param a
* @param b
*/
public void setNumeratorAndDenominator(int a, int b) {
if (b == 0) {
// 运行时异常,编译器不要求必须处理
// 分数的分子可以为零,分母不能为零
throw new RuntimeException("分数不合法,分母为零");
}
int divisor = getGreatestCommonDivisor(Math.abs(a), Math.abs(b));
numerator = a / divisor;
denominator = b / divisor;
// 处理符号问题 eg。-1/-6 显示成 1/6
if (numerator < 0 && denominator < 0) {
numerator = -numerator;
denominator = -denominator;
}
// 后台逻辑 eg。1/7-1/7=0/49,分数合法
// 前台页面处理分子为零,结果显示成数字零
}
public int getNumerator() {
return numerator;
}
public int getDenominator() {
return denominator;
}
/**
* 辗转相除:求两【正整数】最大公约数
* 算法思路:r=m%n,m=n,n=r;r=0,返回n
*
* @param m
* @param n
* @return
*/
static int getGreatestCommonDivisor(int m, int n) {
int r = m % n;
while (r != 0) {
m = n;
n = r;
r = m % n;
}
return n;
}
/**
* 加法运算
*
* @param r
* @return
*/
public Rational add(Rational r) {
int a = r.getNumerator(); // 参数分子
int b = r.getDenominator(); // 参数分母
int newDenominator = denominator * b; // 新分母
int newNumerator = numerator * b + a * denominator; // 新分子
Rational result = new Rational();
result.setNumeratorAndDenominator(newNumerator, newDenominator);
return result;
}
/**
* 减法运算
*
* @param r
* @return
*/
public Rational sub(Rational r) {
int a = r.getNumerator(); // 参数分子
int b = r.getDenominator(); // 参数分母
int newDenominator = denominator * b; // 新分母
int newNumerator = numerator * b - a * denominator; // 新分子
Rational result = new Rational();
result.setNumeratorAndDenominator(newNumerator, newDenominator);
return result;
}
/**
* 乘法运算
*
* @param r
* @return
*/
public Rational muti(Rational r) {
int a = r.getNumerator(); // 参数分子
int b = r.getDenominator(); // 参数分母
int newNumerator = numerator * a; // 新分子
int newDenominator = denominator * b; // 新分母
Rational result = new Rational();
result.setNumeratorAndDenominator(newNumerator, newDenominator);
return result;
}
/**
* 除法运算
*
* @param r
* @return
*/
public Rational div(Rational r) {
int a = r.getNumerator(); // 参数分子
int b = r.getDenominator(); // 参数分母
int newNumerator = numerator * b; // 新分子
int newDenominator = denominator * a; // 新分母
Rational result = new Rational();
result.setNumeratorAndDenominator(newNumerator, newDenominator);
return result;
}
}
一、计算 1/5 和 3/2 四则运算的结果
Rational rational1 = new Rational();
rational1.setNumeratorAndDenominator(1, 5);
Rational rational2 = new Rational();
rational2.setNumeratorAndDenominator(3, 2);
Rational add = rational1.add(rational2);
System.out.println(add.getNumerator() + "/" + add.getDenominator()); // 17/10
Rational sub = rational1.sub(rational2);
System.out.println(sub.getNumerator() + "/" + sub.getDenominator()); // -13/10
Rational muti = rational1.muti(rational2);
System.out.println(muti.getNumerator() + "/" + muti.getDenominator()); // 3/10
Rational div = rational1.div(rational2);
System.out.println(div.getNumerator() + "/" + div.getDenominator());// 2/15
二、求2/1+3/2+5/3+8/5…的前10项和
Rational sum = new Rational();
Rational item = new Rational();
item.setNumeratorAndDenominator(2, 1);
// for循环实现
for (int i = 0; i < 10; i++) { // 校验循环,序缩小次数
sum = sum.add(item);
int fenzi = item.getNumerator(); // 修改中间量
int fenmu = item.getDenominator();
item.setNumeratorAndDenominator(fenzi + fenmu, fenzi);
}
// while循环实现
/*int index = 1, end = 10; // 检验循环,缩小次数
while (index <= end) {
sum = sum.add(item);
index++;
int fenzi = item.getNumerator(); // 修改中间量
int fenmu = item.getDenominator();
item.setNumeratorAndDenominator(fenzi + fenmu, fenzi);
}*/
int a = sum.getNumerator();
int b = sum.getDenominator();
System.out.println("分数表示:" + a + "/" + b); // 998361233/60580520
System.out.println("小数表示:" + a / (b * 1.0)); // 16.479905306194137