2016-05-25 9 views
2

Ich versuche, eine Liste von numBins Zahlen gleichmäßig im Bereich [lower, upper) zu erstellen. Natürlich gibt es Gleitkomma-Probleme und dieser Ansatz ist nicht der beste. Das Ergebnis der Verwendung von Range.Double überrascht mich jedoch, da das fehlende Element überhaupt nicht nahe an der oberen Grenze liegt.Scala Range.Double fehlende letzte Element

Setup:

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

Problem:

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) 

Problem: Die Liste scheint ein Element kurz. ,8181818181818183 ist noch einen Schritt weiter, und kleiner als 1 ist

Umgehung:

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) 

Dieses Ergebnis nun die erwartete Anzahl der Elemente enthält, einschließlich 0,818181 ..

+0

Funktioniert gut für mich (scala 2.11.8). Welche Version von Scala benutzt du? – Marth

+0

Ich habe gerade Ihren Code in meine REPL (Scala 2.10.3 ...) eingefügt und es funktioniert wie erwartet - ich bekomme '0.8181818181818182'. –

+0

Version: Scala Version 2.11.5 (Java HotSpot (TM) 64-Bit Server VM, Java 1.8.0) – blitzen

Antwort

1

Ich denke, die Ursache Ihrer Problem ist, einige Funktionen bei der Umsetzung von toString für NumericRange

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

UPD: Es geht nicht um toString. Einige andere Methoden wie map und foreach schneiden die letzten Elemente aus der zurückgegebenen Sammlung.

Wie auch immer, indem Sie size der Sammlung überprüfen Sie haben - Sie werden herausfinden - alle Elemente sind da.

Was Sie in Ihrem Workaround-Beispiel getan haben - ist ein anderer zugrunde liegender Datentyp.

+0

Danke, bei genauerer Betrachtung: Mit '.size' erhalte ich 12 Elemente. '.last' gibt' 1d'. 'für (i <- rng) println (i)' gibt die gleichen Elemente wie die toString. Indexierung (obwohl zutreffen) erlaubt den Rückruf des 9. Elements (0.636363 ..), aber nicht des fehlenden 10. (0.818181 ..) – blitzen

+0

Versuchen Sie, '.tail' zu überprüfen – Rumoku

+0

Schwanz hat alle Elemente. Wie interessant. Wie kommt es, dass diese Methoden Elemente vermissen? Dies scheint kontraintuitiv zu sein und ist es nicht gegen die Dokumentation? – blitzen