计算机程序设计艺术习题解答(Excercise 1.2.2-25题)

最近突发奇想,想把自己做名著 计算机程序设计艺术(The Art of Computer Programming)(此书名气很大,但能读下去的人寥寥无几)的习题的过程(主要一些比较有意思的习题,太简单的没必要,特别难的说不定我也不会做:))放在网上和人分享。尽管这在国内是非常冷门的一件事,而且工程浩大(输入数学公式效率不高),幸好本人计算机软件专业出身,目前时间比较充裕,闲云野鹤一枚,这种分享至少可以督促我能把这件事持续地做下去,不至于半途而废。

25. [22] 假设有一个二进制电脑和一个二进制实数 x, 1 ≤ x < 2. 证明如下只使用了二进制移位、加法和减法操作(操作数量与 x 的小数点后有效位数成正比)的算法可用于计算 y = \log_b x 的近似值:

L1. [Initialize.] Set y ← 0, z ← x 右移 1 位, k ← 1.

L2. [Test for end.] If x = 1, stop.

L3.[Compare.] If x - z < 1, set z ← z 右移 1 位, k ← k + 1, and repeat this step.

L4. [Reduce values.] Set x ← x - z, z ← x 右移 k 位, y ← y + \log_b{(2^{k}/(2^{k}-1))}, and go to L2.

这个算法看似有些绕,其实原理很简单。假设小数点后有效位数即精度为 p,则 z 的值相当于先将 x 左移 p 位,再右移 k 位,最后再右移 p 位以恢复小数点位置,即 z 始终等于 2^{-p} \lfloor 2^{p-k}x \rfloor(第一个算法不变式),算法的误差就体现在这个\lfloor \rfloor(floor)操作上。

算法的核心在 L4 这步。由于 z\approx x/2^{k},当 x 减掉 z 以后,x 变成了(1-1/2^{k})x = ((2^{k}-1)/2^{k})x

根据对数的特性,有\log_bx = \log_b{((2^{k}-1)/2^{k})x(2^{k}/(2^{k}-1))} = \log_b{((2^{k}-1)/2^{k})x} + \log_b{(2^{k}/(2^{k}-1))}

这样经过 L4 这个步骤后,y+\log_bx 的值始终保持近似恒定(第二个算法不变式),当 x = 1 时算法结束(此时 \log_bx=0 ),此时 y 的值就是最初所求的 \log_bx 的近似值。当然电脑会保存一个辅助的常量表,记录\log_b2, \log_b(4/3), \log_b(8/7), \log_b(16/15) ... 这些常量的值。

此算法最终一定会结束。因为首先 1 ≤ x < 2,x 在算法进行中不断减小并逐渐逼近1(但保持大于等于1),当 x - 1 < 1/2^{p} 时,算法会近似认为 x = 1 并结束。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值