2016-05-25 7 views
2

[lowerupper]の範囲で均等に配置されたnumBinsのリストを作成しようとしています。もちろん、浮動小数点の問題があり、このアプローチは最良ではありません。しかし、Range.Doubleを使用した結果、欠けている要素が上限に近くないため、私は驚きました。Scala Range.Double missing last element

セットアップ:

val lower = -1d 
val upper = 1d 
val numBins = 11 
val step = (upper-lower)/numBins // step = 0.18181818181818182 

問題:

scala> Range.Double(lower, upper, step) 
res0: scala.collection.immutable.NumericRange[Double] = NumericRange(-1.0, -0.8181818181818182, -0.6363636363636364, -0.45454545454545453, -0.2727272727272727, -0.0909090909090909, 0.09090909090909093, 0.27272727272727276, 0.4545454545454546, 0.6363636363636364) 

問題:リストが1つの要素のショートのようです。 0.8181818181818183がさらに一歩であり、1未満

回避策です:

Scala> for (bin <- 0 until numBins) yield lower + bin * step 
res1: scala.collection.immutable.IndexedSeq[Double] = Vector(-1.0, -0.8181818181818181, -0.6363636363636364, -0.4545454545454546, -0.2727272727272727, -0.09090909090909083, 0.09090909090909083, 0.2727272727272727, 0.4545454545454546, 0.6363636363636365, 0.8181818181818183) 

この結果は、今0.818181含む要素の予想数を、含まれてい...

+0

私にとってはうまく動作します(scala 2.11.8)。実行中のスカラのバージョンは何ですか? – Marth

+0

私は自分のコードを自分のREPL(Scala 2.10.3 ...)に貼り付け、期待どおりに動作します。私は '0.8181818181818182'を取得します。 –

+0

バージョン:Scalaバージョン2.11.5(Java HotSpot(TM)64ビットサーバVM、Java 1.8.0) – blitzen

答えて

1

私はあなたの根本的な原因を考えます問題はNumericRange

217 override def toString() = { 
218  val endStr = if (length > Range.MAX_PRINT) ", ...)" else ")" 
219  take(Range.MAX_PRINT).mkString("NumericRange(", ", ", endStr) 
220 } 

UPDためtoStringの実装でいくつかの機能である:それは約toStringではないです。 mapforeachのような他のメソッドは、返されたコレクションの最後の要素を切り捨てます。

とにかくあなたが持っているコレクションのsizeをチェックすることによって、あなたはすべての要素がそこにあることに気付くでしょう。

回避策の例で行ったことは、別の基になるデータ型を使用しています。

+0

おかげさまで、さらに検査してください: '.size'では12個の要素があります。 '.last'は' 1d'を返します。 'for(i < - rng)println(i)'はtoStringと同じ要素を返します。 (テクスチャは適用されますが)9番目の要素(0.636363 ..)を呼び出すことはできますが、10番目の要素は失われません(0.818181 ..)。 – blitzen

+0

'.tail'をチェックしてみてください – Rumoku

+0

テールにはすべての要素があります。なんて面白い。どのようにこれらのメソッドが要素を欠場するのでしょうかこれは直観に反しているように見えますが、ドキュメントに反するものではありませんか? – blitzen