scala学习笔记(二)

if-else

写一个函数使得所有的表达式都满足:
and(x,y) == x && y
or(x,y) == x || y
但是不能使用&&和||。

def and(x:Boolean, y: => Boolean) = if (x) y else false
def or(x:Boolean, y: => Boolean) = if (x) true else y

定义函数-采用牛顿法计算平方根

  def abs(x: Double) = if (x < 0) -x else x       //> abs: (x: Double)Double
  def sqrtIter(guess: Double, x: Double): Double =
    if (isGoodEnough(guess, x)) guess
    else sqrtIter(improve(guess, x), x)           //> sqrtIter: (guess: Double, x: Double)Double
    
  def isGoodEnough(guess: Double, x: Double) =
  	abs(guess * guess - x) < 1e-3             //> isGoodEnough: (guess: Double, x: Double)Boolean
  	
  def improve(guess: Double, x: Double) =
  (guess + x / guess) / 2                         //> improve: (guess: Double, x: Double)Double
  
  def sqrt(x: Double) = sqrtIter(1.0, x)          //> sqrt: (x: Double)Double
  
  sqrt(2)                                         //> res0: Double = 1.4142156862745097
  sqrt(9)                                         //> res1: Double = 3.00009155413138
  sqrt(1e-20)                                     //> res2: Double = 0.03125
/
  sqrt(1e50)  

从eclipse的编译结果来看,当x特别小的时候,计算结果不准确;当x特别大的时候,无法计算出结果,陷入循环。
原因很简单,当x太小时,0.001的阈值就会太高,达不到精度,迭代就停止了,所以不准确。当x太大时,0.001的阈值太低,需要迭代非常多(无尽)的次数才能停止,所以陷入循环。做如下修改就能完美的hold住这两种情况

  def abs(x: Double) = if (x < 0) -x else x       //> abs: (x: Double)Double
  def sqrtIter(guess: Double, x: Double): Double =
    if (isGoodEnough(guess, x)) guess
    else sqrtIter(improve(guess, x), x)           //> sqrtIter: (guess: Double, x: Double)Double
    
  def isGoodEnough(guess: Double, x: Double) =
  	abs(guess * guess - x) < x * 1e-3         //> isGoodEnough: (guess: Double, x: Double)Boolean
  	
  def improve(guess: Double, x: Double) =
  (guess + x / guess) / 2                         //> improve: (guess: Double, x: Double)Double
  
  def sqrt(x: Double) = sqrtIter(1.0, x)          //> sqrt: (x: Double)Double
  
  sqrt(2)                                         //> res1: Double = 1.4142156862745097
  sqrt(9)                                         //> res2: Double = 3.00009155413138
  sqrt(1e-20)                                     //> res3: Double = 1.0000021484861236E-10
  sqrt(1e50)                                      //> res4: Double = 1.0000003807575104E25

分块和词领域

avoid “name-space” pollution

  def sqrt(x: Double) = {

    def sqrtIter(guess: Double, x: Double): Double =
      if (isGoodEnough(guess, x)) guess
      else sqrtIter(improve(guess, x), x) //> sqrtIter: (guess: Double, x: Double)Double

    def isGoodEnough(guess: Double, x: Double) =
      abs(guess * guess - x) < x * 1e-3 //> isGoodEnough: (guess: Double, x: Double)Boolean

    def improve(guess: Double, x: Double) =
      (guess + x / guess) / 2 //> improve: (guess: Double, x: Double)Double

    sqrtIter(1.0, x) //> sqrt: (x: Double)Double
  }

定义在块里的参数,只在块里可见,定义在外面的参数,块里块外都可见,除非块里重复定义了该参数将参数覆盖掉。

由于x在整个块内都是可见的,于是我们可以简化我们的代码,让它看起来更舒服,整洁,减少代码上的冗余。

  def sqrt(x: Double) = {

    def sqrtIter(guess: Double): Double =
      if (isGoodEnough(guess)) guess
      else sqrtIter(improve(guess))

    def isGoodEnough(guess: Double) =
      abs(guess * guess - x) < x * 1e-3

    def improve(guess: Double) =
      (guess + x / guess) / 2

    sqrtIter(1.0)
  }                              

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值