Расчет Scala Double epsilon в функциональном стиле

Предлагаемый подход к вычислению машинного эпсилон с использованием Java выглядит следующим образом:

private static float calculateMachineEpsilonFloat() {
    float machEps = 1.0f;
    do
       machEps /= 2.0f;
    while ((float) (1.0 + (machEps / 2.0)) != 1.0);

    return machEps;
}

Как вычислить эпсилон для scala.Double с помощью Scala в идиоматическом/функциональном стиле из этого предложенного кода?


person elm    schedule 02.07.2014    source источник


Ответы (2)


Это нормально?

scala> val s: Stream[Float] = 1.0f #:: s.map(f => f / 2.0f)
s: Stream[Float] = Stream(1.0, ?)

scala> val eps = s.takeWhile(e => e + 1.0f != 1.0f).last
eps: Float = 1.1920929E-7

Чтобы получить другой эпсилон (2^{-24}), вместо него можно использовать dropWhile (и, следовательно, head).

person tkroman    schedule 02.07.2014

Вы можете переписать цикл do-while с рекурсией:

import scala.annotation.tailrec

def calculateMachineEpsilonFloat = {
  @tailrec
  def calc(machEps: Float): Float = {
    if ((1.0 + (machEps / 2.0)).toFloat != 1.0)
       calc(machEps / 2f)
    else
      machEps
  }
  calc(1f)
}
person wingedsubmariner    schedule 02.07.2014