繁体   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