使这个fibonacci流在溢出之前停止

时间:2014-04-24 22:31:57

标签: scala fibonacci

Scala docs使用Streams

呈现此Fibonacci定义
def fibFrom(a: Int, b: Int): Stream[Int] = a #:: fibFrom(b, a + b)

不幸的是,这会在第47个数字

附近溢出Int
scala> fibFrom(1,1).take(47).toList
res5: List[Int] = List(1, 1, 2, 3, /* snip */, 1836311903, -1323752223)

fibsFrom时,我如何将a.toLong + b.toLong > Int.MaxValue更改为结束

scala> fibsFrom(1,1).take(9999999).toList
res6: List[Int] = List(1, 1, 2, 3, /* snip */, 1836311903)

我尝试了以下操作,但其行为与原始fibFrom

完全相同
def fibFromSafe(a: Int, b: Int): Stream[Int] = {
  if(a.toLong + b.toLong > Int.MaxValue) Stream.cons(a, Stream.cons(b, Stream.empty))
  else Stream.cons(a, fibFromSafe(b, a + b))
}

2 个答案:

答案 0 :(得分:2)

您有一个拼写错误,fibFromSafe会调用您原来的fibFrom

答案 1 :(得分:1)

我刚刚更改了fibFrom的原始定义。如果b为负数,则该函数停止搜索更多数字并返回空流。

  def fibFromSafe(a: Int = 1, b: Int = 1): Stream[Int] = {
    a #:: (if (b > 0) fibFromSafe(b, a + b) else Stream.empty)
  }

  fibFromSafe().take(100).toList

修改

如果您不想检查溢出,可以在> Int.MaxInt的3/5。

def fibFromSafe(a: Int = 1, b: Int = 1): Stream[Int] = {
  a #:: (if (a < Int.MaxValue/5*3) fibFromSafe(b, a + b) else Stream.empty)
}