Instantly share code, notes, and snippets.

# bechny/Complex.scala Created Oct 16, 2013

What would you like to do?
Complex numbers.
 package com.czechscala.blank class Complex(val r: Double, val i: Double) { def this(coord: Tuple2[Double, Double]) = this( coord._1 * Math.cos(coord._2), coord._1 * Math.sin(coord._2) ) def +(other: Complex) = new Complex(r + other.r, i + other.i) def -(other: Complex) = new Complex(r - other.r, i - other.i) def *(other: Complex) = new Complex( r * other.r - i * other.i, i * other.r + r * other.i ) def /(other: Complex) = new Complex( (r * other.r + i * other.i) / (other.r * other.r + other.i * other.i), (i * other.r - r * other.i) / (other.r * other.r + other.i * other.i) ) override def equals(obj: scala.Any) = obj match { case that: Complex => Math.abs((r - that.r) / r) <= 0.001 && Math.abs((i - that.i) / i) <= 0.001 case _ => false } override def toString = { val sign = if (i < 0) '-' else '+' s"(\$r \$sign \${Math.abs(i)}i)" } }
 package com.czechscala.blank import org.scalatest.FunSuite class ComplexTest extends FunSuite { trait ComplexTrait { val c1 = new Complex(1, 2) val c2 = new Complex(3, 4) } test("constructor") { val comp = new Complex(1, 2) assert(comp.r === 1) assert(comp.i === 2) } test("simple adding") { new ComplexTrait { val c3 = new Complex(4, 6) assert(c1 + c2 === c3) } } test("simple subtraction") { new ComplexTrait { val c3 = new Complex(-2, -2) assert(c1 - c2 === c3) } } test("simple multiplication") { new ComplexTrait { val c3 = new Complex(-5, 10) assert(c1 * c2 === c3) } } test("simple division") { new ComplexTrait { val c3 = new Complex(0.44, 0.08) assert(c1 / c2 === c3) } } test("toString") { new ComplexTrait { assert(c1.toString === "(1.0 + 2.0i)") assert(new Complex(-1, 2).toString === "(-1.0 + 2.0i)") assert(new Complex(-1, -2).toString === "(-1.0 - 2.0i)") } } test("equals") { new ComplexTrait { assert(c1 == new Complex(c1.r, c1.i)) assert(c1 != c2) assert(c1 != new Object()) assert(c1 != true) assert(new Complex(1.00001, 1.00004) == new Complex(1, 1)) } } test("construct with polar coordinates") { val c = new Complex((5, 0.92729)) assert(c === new Complex(3, 4)) assert(c != new Complex(3, 40)) } }

### v6ak commented Oct 17, 2013

 Mám tu dvě poznámky. K první doporučuji si něco najít o case classes, hodí se skoro všude. Druhá poznámka bude zajímavá až při řešení syntaxe typu 2+3.i. Metoda equals by šla vyřešit pomocí case classes - začátek deklarace třídy by byl case class Complex(r: Double, i: Double) a dostali byste "zdarma" metodu equals plus další metody (např. hashCode, na které jste zapomněli). Tady to zatím není moc vidět, ale pokud bychom chtěli umožnit zápis 3+2.i, museli bychom udělat dvě* implicitní konverze (řekněme realToComplex pro operace mezi reálnými a komplexními čísly a k tomu realComplexConversions pro výraz 2.i) hodilo by se přejmenovat field `i` na něco jiného. Jinak by asi vznikla nejednoznačnost u implicitních konverzí - 2.i by se mohlo vyhodnotit a) buď jako realToComplex(2).i (tedy by se to snažilo zjistit imaginární složku z dvojky, která by samozřejmě byla nulová, tedy 0.0) b) nebo jako realComplexConversions(2).i, což by mělo vrátit Complex(0, 2). *) OK, zanedbávám, že reálné číslo může být vyjádřeno nejen typem Double, ale i Float nebo dokonce Int apod. Pro zjednodušení.