Domanda

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

Oh. Annoying. I was hoping I could do something like:

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

...and avoid Infinity for f(0.0). Let's try to find a slightly bigger number:

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)

OK. Good. It's increasing. How about:

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

Hum... maybe it's going to take a while. Let's try:

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

...and I'm still waiting on this one. Doesn't seem like it's going to terminate anytime soon.

How can I find the smallest Double divisor that won't give an infinite result?

È stato utile?

Soluzione

If you're going to search, at least search with bisection which should take no more than about 1024 iterations since that's 2(#bits in exponent).

But it turns out that you don't need to because you can find it by trial even faster. It should be very close to 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

Not so bad.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top