Question

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?

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top