簡體   English   中英

如何為 Double 生成 Scala 范圍?

[英]How to generate Scala Range for Double?

我無法為 Double 生成 Scala 范圍。

我已經閱讀了 StackOverflow 並且有許多片段顯示了雙范圍,但這些片段都不適用於我的 Scala REPL 2.13.0

9.474 to 49.474 by 1.0
1d to 1000d by 1d
(1.0 to 2.0 by 0.01)
            ^
       error: value to is not a member of Double

我不能使用 to 和 by 在我的 Scala REPL 中生成雙范圍的原因是什么

我在使用 Scala 2.13.0 的 macOS 上

使用Scala 2.12,我會收到棄用警告:

scala> 9.474 to 49.474 by 1.0
<console>:12: warning: method to in trait FractionalProxy is deprecated (since 2.12.6): use BigDecimal range instead
       9.474 to 49.474 by 1.0

因此,也許在2.13中不再受支持。 根據警告,您可以執行以下操作:

scala> BigDecimal(9.474) to BigDecimal(49.474) by BigDecimal(1.0)
res6: scala.collection.immutable.NumericRange.Inclusive[scala.math.BigDecimal] = NumericRange 9.474 to 49.474

這也適用:

BigDecimal(9.474) to BigDecimal(49.474) by 1

如果在兩個版本上都使用.foreach(println) ,則會看到沒有BigDecimal的結果看起來不太好:

9.474
10.474
..
31.474
32.474000000000004
33.474000000000004
...

發行說明中

整個標准庫中已棄用的各種方法和類已完全刪除。

您始終可以創建自己的 function,它將為您創建 Range(或 Seq/Iterator)。

// https://scastie.scala-lang.org/ZPfpF37bRlKfUPnMyOzJDw

import scala.util.Try

def rangeInclusiveDouble(from:Double, to:Double, by:Double = 1.0) = {
  assume(by != 0, "'by' cannot by 0")
  assume((to - from) * by > 0, "range has reversed order (arguments 'from', 'to' and 'by' will produce infinite range)")
  val check: Double => Boolean = if (by > 0) _ <= to else _ >= to
  Iterator.iterate(from)(_+by).takeWhile(check)
}

//usage example:
rangeInclusiveDouble(1.1, 5.1).toSeq
//List(1.1, 2.1, 3.1, 4.1, 5.1)
rangeInclusiveDouble(1.1, 2.1, 0.1).toSeq //here you will see why range over double is tricky!
//List(1.1, 1.2000000000000002, 1.3000000000000003, 1.4000000000000004,...
Try(rangeInclusiveDouble(5.0, 1.0).toSeq)
// Failure(java.lang.AssertionError: assumption failed: range has reversed order (arguments 'from', 'to' and 'by' will produce infinite range))
Try(rangeInclusiveDouble(5.0, 1.0, 0).toSeq)
//Failure(java.lang.AssertionError: assumption failed: 'by' cannot by 0)
rangeInclusiveDouble(5.0, 1.0, -1).toSeq
//List(5.0, 4.0, 3.0, 2.0, 1.0)

如您所見,它有其自身的問題……但如果您注意范圍限制,則可以使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM