Scala poprawa kodu

0
object Main extends App {
  def sqrt(x: Double) = {
    def square(num: Double): Double =
      num * num
    def sqrtIter(guess: Double): Double = 
      if (isGoodEnough(guess)) guess 
      else sqrtIter(improve(guess))
    def improve(guess: Double) =
      (guess + x / guess) / 2
    def isGoodEnough(guess: Double) =
      math.abs(square(guess) - x) < 0.001 * x
    sqrtIter(1.0)
  }

porównanie jej działania ze standardową funkcją biblioteczną math.sqrt:

math.sqrt(2) // > res0: Double = 1.4142135623730951
sqrt(2) // > res1: Double = 1.4142156862745097

math.sqrt(0.001) > res2: Double = 0.03162277660168379
math.sqrt(0.1e-20) > res3: Double = 3.1622776601683794E-11
math.sqrt(1.0e20) > res4: Double = 1.0E10
math.sqrt(1.0e50) > res5: Double = 1.0E25
sqrt(0.001) > res6: Double = 0.04124542607499115
sqrt(0.1e-20) > res7: Double = 0.03125
sqrt(1.0e20) > res8: Double = 1.0E10\
sqrt(1.0e50)

wszystko wydaje się być w porządku, ale dokładność znacząco spada dla małych
liczb, zaś dla dużych program w ogóle nie kończy pracy jak poprawić aby wyniki pracy obu funkcji były takie same przynajmniej dla trzech pierwszych cyfr znaczących czy ktoś ma jakiś pomysł ?

1

Pomnóż dokładność przez x. Czyli:

    def isGoodEnough(guess: Double) =
      math.abs(square(guess) - x) < 0.001 * x

Całość: http://ideone.com/XQCfs7

Dokładność można nawet znacząco zwiększyć, a program się dalej zatrzymuje: http://ideone.com/kRKYUb

Update:
Można też wyrzucić dokładność i iterować dopóki jest poprawa: http://ideone.com/XLieaM
Wyniki wychodzą czasem inne niż przy java.lang.Math, ale są raczej tak samo dobre.

0

dzięki :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1