《编程原本 》一3.4 处理特殊情况的过程

简介: 本节书摘来自华章出版社《编程原本 》一书中的第3章,第3.4节,作者(美)斯特潘诺夫(Stepanov, A.),(美)麦克琼斯(McJones, P.),更多章节内容可以访问云栖社区“华章计算机”公众号查看

3.4 处理特殊情况的过程

在上面的最后版本里用到下面运算:
n / I(2)
n % I(2) == I(0)
n % I(2) != I(0)
n == I(0)
n == I(1)
其中/和%的代价很高.对无符号整数或有符号整数的非负值,可以用移位和掩码运算来代替它们.
识别出程序里经常出现的表达式,其中涉及一些过程或某种类型的常量.将它们定义为相应的特殊情况过程常常很有价值.针对特殊情况的实现经常比一般情况的处理更高效,因此应该把这类过程放入类型的计算基.对语言的内部类型,通常存在针对特殊情况的机器指令.对用户定义类型,针对特殊情况的优化也常有显著效果.举例说,两个任意多项式的除法比一个多项式除以x难得多.与此类似,两个高斯整数(形式为a+bi的数,其中a和b都是整数而i=√.1)相除比一个高斯整数除以1+i难得多.
任何整数类型都应该提供下面的特殊情况过程:
image

image

练习3.2请为C++的各整数类型实现上面这些过程.
现在可以给出求幂过程的最后实现了,其中用到一些特殊情况过程:

template<typename I, typename Op> 
requires(Integer(I) && BinaryOperation(Op)) 
Domain(Op) power accumulate positive(Domain(Op) r, 
Domain(Op) a, I n, 
Op op) 
{ 
//前条件:associative(op)∧positive(n)
while (true) { 
if (odd(n)) { 
r = op(r, a); 

if (one(n)) return r; 
} 
a = op(a, a); 
n = half nonnegative(n); 
} } 
template<typename I, typename Op> requires(Integer(I) && BinaryOperation(Op)) Domain(Op) power accumulate(Domain(Op) r, Domain(Op) a, I n, Op op) 
{ 
//前条件:associative(op)∧.negative(n)
if (zero(n)) return r; 
return power accumulate positive(r, a, n, op); } 
template<typename I, typename Op> 
requires(Integer(I) && BinaryOperation(Op)) Domain(Op) power(Domain(Op) a, I n, Op op) { 
//前条件:associative(op)∧positive(n)
while (even(n)) {a = op(a, a);n = half nonnegative(n);
} 
n = half nonnegative(n); 
if (zero(n)) return a; 
return power accumulate positive(a, op(a, a), n, op); }

由于已知a n+m = a n a m , 表达式a 0 必须求出运算op的单位元.可以把单位元作为操作的另一参数传入,将power的定义扩充到包括0次幂:6

template<typename I, typename Op> 
requires(Integer(I) && BinaryOperation(Op)) 
Domain(Op) power(Domain(Op) a, I n, Op op, Domain(Op) id) 
{ 
//前条件:associative(op)∧.negative(n)
if (zero(n)) return id; 
return power(a, n, op); 
}

项目3.1浮点乘法和加法不可结合,用于作为power或powerleftassociated的运算就可能得到不同结果.请设法弄清,在求浮点数的整数次幂时,是power还是powerleftassociated能给出更准确的结果.

相关文章
|
5月前
|
存储 算法
C标准库函数的工作细节
C标准库函数的工作细节
|
5月前
|
算法 程序员
为何程序员在编写程序时难以一次性将所有代码完美无瑕地完成,而是需要经历反复修改Bug的过程?
为何程序员在编写程序时难以一次性将所有代码完美无瑕地完成,而是需要经历反复修改Bug的过程?
59 7
|
存储 安全 程序员
程序员思维模式-主调试循环
仅通过测试进行验证基本上是在仪器上驾驶飞机,而不是能够向外看挡风玻璃。视觉飞行和肌肉记忆飞行与仪器相结合,既高效又安全。你不太可能误撞山。 当你已经编码了十多年时,可能很难重新捕捉初学者的思想,并向新手解释如何像程序员一样思考。我记得在大学里,当我编码的时间相对较短时,有一件事在我的脑海中结晶了编写代码背后的思维过程——你可以称之为程序员哲学。我正在帮助一个朋友完成计算机
程序员思维模式-主调试循环
|
存储 安全 程序员
程序员思维模式 - 主调试循环
> 仅通过测试进行验证基本上是在仪器上驾驶飞机,而不是能够向外看挡风玻璃。视觉飞行和肌肉记忆飞行与仪器相结合,既高效又安全。你不太可能误撞山。 当你已经编码了十多年时,可能很难重新捕捉[初学者的思想](https://en.wikipedia.org/wiki/Shoshin),并向新手解释如何像程序员一样思考。我记得在大学里,当我编码的时间相对较短时,有一件事在我的脑海中结晶了编写代码背后的思维过程——你可以称之为程序员哲学。我正在帮助一个朋友完成计算机科学101任务。他们对编码完全陌生。 他们从头到尾在纸上写了一个完整的解决方案——也许是100行代码。然后,他们将其全部输入到文本编辑器
132 0
|
设计模式 缓存 前端开发
可否举例说明你在工作中是如何优化前端代码的?
可否举例说明你在工作中是如何优化前端代码的?
179 0
|
算法
【自然框架】重新整理后的自然框架源码!
  整理后的自然框架源码,有九个项目,可以看下面的脑图,带“对号”的表示是一个独立的项目。后面的是主要内容。     欢迎下载http://www.naturefw.com/Down/kind38/List1.aspx ,但是请保留源码里的版权信息,以及dll里的版权信息。
775 0
|
前端开发 大数据 程序员
还在看视频读文档学编程?这有7种编程学习方式,哪种最适合你?
学习编程不仅仅是学会各种语言,你还需要学习如何像程序员一样思考。这里有七种学习编程的方式,视频、文档、听觉、触摸……,你需要找到最适合你的那种。
1849 0
C过程思想,根据需求写方法就行
实现的方法有多种 Comprehensive orientate 2017/10/27 13:25:07C过程思想,根据需求写方法就行     
709 0
|
程序员
《编程原本 》一1.4 过程
本节书摘来自华章出版社《编程原本 》一书中的第1章,第1.4节,作者(美)斯特潘诺夫(Stepanov, A.),(美)麦克琼斯(McJones, P.),更多章节内容可以访问云栖社区“华章计算机”公众号查看
947 0