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?
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.