Last active
January 27, 2017 04:50
-
-
Save akaneko3/6a196a1055598f6f2bc3 to your computer and use it in GitHub Desktop.
Scala で分数を扱う ref: http://qiita.com/akaneko3/items/e23f2b2f7bd8f4940cec
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package jp.mydns.akanekodou.scala | |
import math.Rational | |
object Main extends App { | |
// ここから | |
implicit val RationalIsFractional = new Fractional[Rational] { | |
// compare の実装 | |
def compare(x : Rational, y : Rational) : Int = | |
(x.numerator * y.denominator) compare (x.denominator * y.numerator) | |
// 四則演算 | |
def plus(x : Rational, y : Rational) : Rational = | |
Rational(x.numerator * y.denominator + x.denominator * y.numerator ,x.denominator * y.denominator) | |
def minus(x : Rational, y : Rational) : Rational = | |
Rational(x.numerator * y.denominator - x.denominator * y.numerator ,x.denominator * y.denominator) | |
def times(x : Rational, y : Rational) : Rational = | |
Rational(x.numerator * y.numerator, x.denominator * y.denominator) | |
def div(x : Rational, y : Rational) : Rational = | |
Rational(x.numerator * y.denominator, x.denominator * y.numerator) | |
// 正負反転 | |
def negate(x : Rational) : Rational = Rational(- x.numerator, x.denominator) | |
// 型変換 | |
def fromInt(x : Int) : Rational = Rational(x) | |
def toInt(x : Rational) : Int = (x.numerator / x.denominator).toInt | |
def toLong(x : Rational) : Long = (x.numerator / x.denominator).toLong | |
def toFloat(x : Rational) : Float = | |
x.numerator.toFloat / x.denominator.toFloat | |
def toDouble(x : Rational) : Double = | |
x.numerator.toDouble / x.denominator.toDouble | |
} | |
import scala.math.Fractional.Implicits._ | |
import scala.math.Ordering.Implicits._ | |
// ここまでを Main の外に出したい ! | |
val a = Rational(2, 12) | |
val b = a.copy(n = 3) | |
val c = a + b | |
println(a, b, a + b, a == b, a < b) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
case class NewRational(n : BigInt, d : BigInt = 1) extends Fractional[NewRational] { | |
require(d != 0) // 分母は 0 でないことを要求する | |
private val g : BigInt = n gcd d | |
val numerator : BigInt = n * d.signum / g // 分子 | |
val denominator : BigInt = d * d.signum / g // 分母(分母は必ず正) | |
def compare(x : NewRational, y : NewRational) : Int = | |
(x.numerator * y.denominator) compare (x.denominator * y.numerator) | |
def plus(x : NewRational, y : NewRational) : NewRational = | |
NewRational(x.numerator * y.denominator + x.denominator * y.numerator ,x.denominator * y.denominator) | |
def minus(x : NewRational, y : NewRational) : NewRational = | |
NewRational(x.numerator * y.denominator - x.denominator * y.numerator ,x.denominator * y.denominator) | |
def times(x : NewRational, y : NewRational) : NewRational = | |
NewRational(x.numerator * y.numerator, x.denominator * y.denominator) | |
def div(x : NewRational, y : NewRational) : NewRational = | |
NewRational(x.numerator * y.denominator, x.denominator * y.numerator) | |
def negate(x : NewRational) : NewRational = NewRational(- x.numerator, x.denominator) | |
def fromInt(x : Int) : NewRational = NewRational(x) | |
def toInt(x : NewRational) : Int = (x.numerator / x.denominator).toInt | |
def toLong(x : NewRational) : Long = (x.numerator / x.denominator).toLong | |
def toFloat(x : NewRational) : Float = | |
x.numerator.toFloat / x.denominator.toFloat | |
def toDouble(x : NewRational) : Double = | |
x.numerator.toDouble / x.denominator.toDouble | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package jp.mydns.akanekodou.scala.math | |
// 分数クラス(分母はデフォルトで 1) | |
case class Rational(n : BigInt, d : BigInt = 1) { | |
require(d != 0) // 分母は 0 でないことを要求する | |
private val g : BigInt = n gcd d | |
val numerator : BigInt = n * d.signum / g | |
val denominator : BigInt = d * d.signum / g | |
// toString の override | |
override def toString() : String = | |
s"${numerator}" + (if (denominator != 1) s"/${denominator}" else "") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment