我正在学习scala并享受它,它是一种非常强大的语言。我写了这个程序来解决Euler#2问题,来自项目欧拉。它可以找到甚至斐波纳契数字< 400万(称为最大#)的总和。Stream上的scala过滤器产生错误的结果
首先我用takeWhile,然后过滤:
fib().takeWhile(_ < n).filter(_ % 2 == 0).sum
然后决定takeWhile之前更改顺序,并使用过滤器:
fib().filter(_ % 2 == 0).takeWhile(_ < n).sum
我这样做是为了检查是否有性能差异当增加最大#时。如预期的那样,结果是准确的,并且性能几乎相同,直到我使用此输入数字(40000000000000)并得到2个不同的结果。结果是:
$ scala com.ms.E2_1 40000000000000
takeWhile 1st => 3770056902373173214
filter 1st => -8573983172444283806
有人能解释为什么我在使用filter之前得到这个错误吗?谢谢。
object E2_1 {
def fib(a: Long = 0, b: Long = 1): Stream[Long] = {
a #:: fib(b, a + b)
}
def main(args: Array[String]): Unit = {
if (args.length == 1) {
val n = args(0).toLong
println("takeWhile 1st \t=> " + fib().takeWhile(_ < n).filter(_ % 2 == 0).sum)
println("filter 1st \t=> " + fib().filter(_ % 2 == 0).takeWhile(_ < n).sum)
} else {
println("missing args")
}
}
}
看起来你刚刚溢出。在数学上,你的'fib'可能会单调递增,但实际上你使用的是两个补码“Long”,一旦它们变得足够大,它们就会翻牌。或者如果不是流值本身,那么它们的总和。 – copumpkin 2013-05-01 04:43:23
非常感谢copumpkin,但为什么在使用过滤器之前使用过滤器而不是其他方式溢出? – Mark 2013-05-01 04:54:02