scala写的分数类, 支持+-*/约分, 当左操作数约分设为true, 所有结果约分设为true, 可惜还是用了var
// 2012/5/15
// let it go
看了一个Java写的功能完全一样的分数类, 80+行, 不包括注释和空白行, scala39行搞定了
*******************************************************************************************************
扩充分数类, 实现前置一元操作符取负-, 取倒数~, 实现不等号比较, 实现跨类型计算(implicit conversion)
// 2012/5/16
object Rational {
implicit def toRational(a: Any) = {
var d = a.toString.toDouble
var numer = d
var denom = 1
while (numer != numer.ceil) {
numer *= 10
denom *= 10
}
new Rational(numer.toInt, denom.toInt).--
}
}
class Rational(x: Int, y: Int){
require(y != 0)
val numer = x
val denom = y
private val cd = gcd(numer abs, denom abs)
private var autoreduce = false
def getAutoreduce = autoreduce
def setAutoreduce(bool: Boolean) = autoreduce = bool
def -- : Rational = new Rational(numer / cd, denom / cd)
private def fuc(x: Int, y: Int): Rational = {
var ra = new Rational(x, y)
if (autoreduce) {
ra = ra.--
ra.setAutoreduce(true)
}
ra
}
def +(b: Rational) = fuc(numer * b.denom + denom * b.numer, denom * b.denom)
def -(b: Rational) = fuc(numer * b.denom - denom * b.numer, denom * b.denom)
def *(b: Rational) = fuc(numer * b.numer, denom * b.denom)
def /(b: Rational) = {
require(b != 0)
fuc(numer * b.denom, denom * b.numer)
}
def unary_+ = this
def unary_- = {
val ra = new Rational(-numer, denom)
if (autoreduce) ra.setAutoreduce(true)
ra
}
def unary_~ = {
require(numer != 0)
val ra = new Rational(denom, numer)
if (autoreduce) ra.setAutoreduce(true)
ra
}
override def equals(b: Any): Boolean = b match{
case b: Rational => {
val c = this.--
val d = b.--
c.toDouble * d.toDouble >= 0 && c.numer.abs == d.numer.abs && c.denom.abs == d.denom.abs
}
case _ => this.toDouble == b
}
def >=(b: Rational) = (this - b) isPositive
def <=(b: Rational) = !(this >= b) || this == b
def >(b: Rational) = !(this <= b)
def <(b: Rational) = !(this >= b)
private def isPositive = numer * denom >= 0
override def toString(): String = {
if (this.toDouble < 0) {
"-" + numer.abs + "/" + denom.abs
}else "" + numer.abs + "/" + denom.abs
}
def toDouble : Double = numer.toDouble / denom.toDouble
private def gcd(x: Int, y: Int): Int = if (y == 0) x else gcd(y, x % y)
}