【问题标题】:How can I find the smallest `Double` divisor that won't give an infinite result?如何找到不会给出无限结果的最小“双”除数?
【发布时间】:2013-02-23 21:28:24
【问题描述】:
Welcome to Scala version 2.9.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_26).

scala> 1.0 / Double.MinPositiveValue
res0: Double = Infinity

哦。恼人的。我希望我能做这样的事情:

def f(x: Double) = 1.0 / (x + Double.MinPositiveValue)

...避免Infinity 使用f(0.0)。让我们试着找一个稍微大一点的数字:

scala> val xs = Iterator.iterate(Double.MinPositiveValue)(_ + Double.MinPositiveValue)
xs: Iterator[Double] = non-empty iterator

scala> xs.take(10).toList
res1: List[Double] = List(4.9E-324, 1.0E-323, 1.5E-323, 2.0E-323, 2.5E-323, 3.0E-323, 3.5E-323, 4.0E-323, 4.4E-323, 4.9E-323)

好的。好的。它在增加。怎么样:

scala> xs.map(1.0 / _).take(10).toList
res2: List[Double] = List(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity)

嗯...也许需要一段时间。让我们试试吧:

scala> xs.find(x => !(1.0 / x).isInfinite)

...我还在等这个。它似乎不会很快终止。

如何找到不会给出无限结果的最小 Double 除数?

【问题讨论】:

  • 经过一番反复试验,我几乎可以确定号码是5.56268464626801E-309
  • 你为什么要找这个神奇的数字?
  • @RandallSchulz 查看我对f 的定义。更多背景信息:我通过它们与其他事物的距离的倒数来加权事物。如果那个距离为零,我想要一个很大的权重,但也不是无限的......

标签: scala double divide-by-zero


【解决方案1】:

如果您要搜索,至少使用二等分进行搜索,这应该不超过大约 1024 次迭代,因为那是 2(指数中的#bits)

但事实证明你不需要,因为你可以更快地通过试用找到它。应该很接近1/Double.MaxValue:

scala> Double.MaxValue
res35: Double = 1.7976931348623157E308

scala> 1/res35
res36: Double = 5.562684646268003E-309

scala> 1/res36
res37: Double = Infinity

scala> 1/(res36+math.ulp(res36))
res38: Double = 1.7976931348623143E308

scala> res36+math.ulp(res36)
res39: Double = 5.56268464626801E-309

还不错。

【讨论】:

  • 我觉得有点令人不安的是1 / ( 1 / Double.MaxValue ) == Double.MaxValuefalse。但我想这是一个浮点运算的事情:)
猜你喜欢
  • 2012-01-27
  • 2012-07-09
  • 2017-04-10
  • 2012-12-11
  • 1970-01-01
  • 2015-06-17
  • 1970-01-01
  • 1970-01-01
  • 2019-05-17
相关资源
最近更新 更多