一个分数类的实现——Rational类
2018-02-15 22:42
316 查看
分数是我们从小学就开始接触的一类有理数,但是在计算机中只有浮点型数据。我们今天(除夕)就来实现一个分数类,以见证这历史性的时刻。
从最基础的分数结构来思考,我们需要一个分子分母,比如这样:public class Rational {
private int num; /* The numerator of this Rational */
private int den; /* The denominator of this Rational */
public Rational(int x, int y) {
num = x;
den = y;
}
}我们一开始很容易这样写,但这样写是有很大问题的。例如算术运算规则对分子和分母的值有限制,这里面最明显的限制就是分母不能为0。构造器应该检查这种情况并在分母为0时抛出异常。还有,这样的分数不是最简形式,我们会有很多种不同的方式来表示同一个有理数。比如三分之一:
1/3 2/6 100/300 -1/-3 ...
要处理这些问题,我们先遵循数学家们给的规则:
1.分数总是表示为最简形式,分子分母要同时处理它们的最大公约数。可以使用gcd方法求分子分母的最大公约数。
2.分母总是整数,也就是分数值是和分子一起存储的。
3.有理数0总是表示为分数0/1。
这样我们就比较容易地写出分数类的构造器了!当然,我们还可能需要传一个分母为1的假分数,这时直接把分子传给一个参数的构造器就行,我们用this关键字调用已经写好的构造器。
我们还要给分数器增加算术运算的方法以及通用的toString方法,所以代码的一种可能实现为:public class Rational {
private int num;
private int den;
public Rational() {
this(0);
}
public Rational(int n) {
this(n, 1);
}
public Rational(int x, int y) {
if (y == 0) throw new RuntimeException("Division by zero");
if (x == 0) {
num = 0;
den = 1;
} else {
int g = gcd(Math.abs(x), Math.abs(y));
num = x / g;
den = Math.abs(y) / g;
if (y < 0) num = -num;
}
}
public Rational add(Rational r2) {
return new Rational(this.num * r2.den + r2.num * this.den, this.den * r2.den);
}
public Rational substract(Rational r2) {
return new Rational(this.num * r2.den - r2.num * this.den, this.den * r2.den);
}
public Rational multiply(Rational r2) {
return new Rational(this.num * r2.num, this.den * r2.den);
}
public Rational divide(Rational r2) {
return new Rational(this.num * r2.den, this.den * r2.num);
}
@Override
public String toString() {
if (den == 1)
return "" + num;
return num + "/" + den;
}
private int gcd(int x, int y) {
int r = x % y;
while (r != 0) {
x = y;
y = r;
r = x % y;
}
return y;
}
}
放爆竹的时光一去不复还,这个类设计地真好,不得不从书上借鉴过来!
从最基础的分数结构来思考,我们需要一个分子分母,比如这样:public class Rational {
private int num; /* The numerator of this Rational */
private int den; /* The denominator of this Rational */
public Rational(int x, int y) {
num = x;
den = y;
}
}我们一开始很容易这样写,但这样写是有很大问题的。例如算术运算规则对分子和分母的值有限制,这里面最明显的限制就是分母不能为0。构造器应该检查这种情况并在分母为0时抛出异常。还有,这样的分数不是最简形式,我们会有很多种不同的方式来表示同一个有理数。比如三分之一:
1/3 2/6 100/300 -1/-3 ...
要处理这些问题,我们先遵循数学家们给的规则:
1.分数总是表示为最简形式,分子分母要同时处理它们的最大公约数。可以使用gcd方法求分子分母的最大公约数。
2.分母总是整数,也就是分数值是和分子一起存储的。
3.有理数0总是表示为分数0/1。
这样我们就比较容易地写出分数类的构造器了!当然,我们还可能需要传一个分母为1的假分数,这时直接把分子传给一个参数的构造器就行,我们用this关键字调用已经写好的构造器。
我们还要给分数器增加算术运算的方法以及通用的toString方法,所以代码的一种可能实现为:public class Rational {
private int num;
private int den;
public Rational() {
this(0);
}
public Rational(int n) {
this(n, 1);
}
public Rational(int x, int y) {
if (y == 0) throw new RuntimeException("Division by zero");
if (x == 0) {
num = 0;
den = 1;
} else {
int g = gcd(Math.abs(x), Math.abs(y));
num = x / g;
den = Math.abs(y) / g;
if (y < 0) num = -num;
}
}
public Rational add(Rational r2) {
return new Rational(this.num * r2.den + r2.num * this.den, this.den * r2.den);
}
public Rational substract(Rational r2) {
return new Rational(this.num * r2.den - r2.num * this.den, this.den * r2.den);
}
public Rational multiply(Rational r2) {
return new Rational(this.num * r2.num, this.den * r2.den);
}
public Rational divide(Rational r2) {
return new Rational(this.num * r2.den, this.den * r2.num);
}
@Override
public String toString() {
if (den == 1)
return "" + num;
return num + "/" + den;
}
private int gcd(int x, int y) {
int r = x % y;
while (r != 0) {
x = y;
y = r;
r = x % y;
}
return y;
}
}
放爆竹的时光一去不复还,这个类设计地真好,不得不从书上借鉴过来!
相关文章推荐
- 创建一个分数类,实现分数的加减乘除
- 实现一个用分子分母的格式来表示有理数的结构体rational以及相关的函数,rational结构体之间可以做加减乘除运算,运算的结果仍然是rational
- OC基础第三天(定义一个分数类,实现加减乘除!)
- C语言 编写一个函数reverse_string(char * string) 实现:将参数字符串中的字符反向排列。 要求:不能使用C函数库中的字符串操作函数。
- 一个ios手势密码功能实现
- 实现一个线程池
- 功能实现:点击一个链接进入另一个链接所指向的内容
- 写出一个你自己的MVC框架-基于对springMVC源码实现和理解(3):数据初始化(二)
- 如何用两个栈实现一个队列,以及用两个队列实现一个栈
- "Unicode"编码,java实现一个按字节截取字符串的子串的方法
- 一个javascript的Math对象的方法实现,将字符串,转换成实际函数
- java 实现输入一个字符串,打印出其中所有的数字
- cocos2dx-3.3 lua实现一个单选按钮
- 写一个函数,实现字符串的复制
- 封装实现一个自己的tabbar
- C++实现一个LRU Cache
- 再发一个J2ME和WAP网页实现拨号功能(很有价值哦)
- 一个同步打印机的实现
- C语言枚举进程,实现一个简单的内存补丁
- 一个简易网络嗅探器的实现