2017-02-22 4 views
0
def solve(a: Double, b: Double, c: Double): Option[(Double, Double)]= { 
val disc = b*b - 4 * a * c; 
val root1 = (-b + disc)/2*a); 
val root2 = (-b - disc)/2*a); 
} 

は、私が(ROOT1、root2)はタプルを作成することを理解し、そして私は、オプションのタイプでタプルを返すようにしたいです。スカラーでどうやってやるの?ScalaでOption型で複数の値を返すにはどうすればよいですか?

+2

何がA'が0であるとき、 '返すようにしようとしていますか? – Brian

+0

@Brian明らかに無限:) – prayagupd

+1

を私は 'NONE'を推測@Brian?私も何を実装しないようにしようとしたので、 – Yawar

答えて

2

他の回答は、私はあなたがやろうとしている推測しているものの部分をカバーし、しかし、私が考えることのない全体は、次のとおりです。何の解決策が存在しない場合は次の式が戻って根のペアまたはNoneのいずれかを実装します。それを考えると、現在の実装では、数式が正しく計算されていません。参考のため、式は次のとおりです。

x1 = (-b + sqrt(b^2 - 4ac))/2a 
x2 = (-b - sqrt(b^2 - 4ac))/2a 

正しい実装:

def solve(a: Double, b: Double, c: Double): Option[(Double, Double)] = { 
    val sqrtDiscriminant = Math.sqrt(b * b - 4 * a * c) 
    val twiceA = a * 2 

    if (a == 0) None 
    else 
    Some(
     ((-b + sqrtDiscriminant)/twiceA, 
     (-b - sqrtDiscriminant)/twiceA)) 
} 
0

@WillDによって提供さ答えからあなたのコメントに基づいて、あなたが、例外が発生したときにNoneを返すようにしたいようだ(root1またはroot2のいずれかを計算することで、おそらく?)この場合、あなたはscala.util.Tryで各計算を包囲し、それぞれに結果を変換することができOption

import scala.util.Try 

def solve(a: Double, b: Double, c: Double): Option[(Double, Double)] = { 
    val disc = b*b - 4 * a * c 
    val root1: Option[Double] = Try((-b + disc)/(2*a)).toOption 
    val root2: Option[Double] = Try((-b - disc)/(2*a)).toOption 

    // If both `root1` and `root2` are calculated successfully, return the tupled values. 
    for { 
    r1 <- root1 
    r2 <- root2 
    } yield { 
    (r1, r2) 
    } 
} 

我々は値でこのメソッドを呼び出すと

scala> solve(0,1,0) 
res0: Option[(Double, Double)] = Some((NaN,-Infinity)) 

私は、なぜ完全にわからないんだけど、私はそれがDoubleの不正確さに関係していると信じて:01、および0、私たちは奇妙な何かが起こる気づきます。うまくいけば、他の誰かが、なぜこれがNaN-Infinityを返すのかというより良い答えでチャイムインすることができます。しかし、我々はBigDecimalDoubleのすべての出現を交換する場合、私たちはより良い精度を得るだけでなく、所望の出力:

import scala.util.Try 

def solve(a: BigDecimal, b: BigDecimal, c: BigDecimal): Option[(BigDecimal, BigDecimal)] = { 
    val disc = b*b - 4 * a * c 
    val root1: Option[BigDecimal] = Try((-b + disc)/(2*a)).toOption 
    val root2: Option[BigDecimal] = Try((-b - disc)/(2*a)).toOption 

    // If both `root1` and `root2` are calculated successfully, return the tupled values. 
    for { 
    r1 <- root1 
    r2 <- root2 
    } yield { 
    (r1, r2) 
    } 
} 

scala> solve(0,1,0) 
res1: Option[(BigDecimal, BigDecimal)] = None 
関連する問題