Skip to content

Instantly share code, notes, and snippets.

@akaneko3
Last active January 27, 2017 04:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save akaneko3/6a196a1055598f6f2bc3 to your computer and use it in GitHub Desktop.
Save akaneko3/6a196a1055598f6f2bc3 to your computer and use it in GitHub Desktop.
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)
}
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
}
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