dc计算器简介
本帖最后由 cjaizss 于 2011-04-17 09:20 编辑
虽然没想明白这个东西有什么实际用处,bc完全可以用一种更可观的方式来代替dc.
但用来做做智力体操,还是有点意思的。
简介自四楼起
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
本帖最后由 cjaizss 于 2011-04-17 09:20 编辑
虽然没想明白这个东西有什么实际用处,bc完全可以用一种更可观的方式来代替dc.
但用来做做智力体操,还是有点意思的。
简介自四楼起
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(9)
不过想来也还是有实际用处,用来写脚本,有的时候产生逆波兰更容易一些
好,偶写一个简单的dc教材吧。
首先,dc是一个计算器。但其操作习惯不同于我们常用的中缀式,而采用逆波兰式的方法。
所谓中缀式,即操作符穿插于操作数之间。而逆波兰式则不是,操作符在操作数之后,其好处在于无需复杂的语法,无需操作符优先级。
逆波兰式的计算是要先建一个栈,遇到操作数进栈,遇到操作符,比如是n元的操作符,则从栈定出栈n个元,计算完了再把结果进栈。
比如
(1+2)*4的逆波兰式为
1 2 + 4 *
计算过程为
初始:栈空
--栈顶--
--栈底--
1进栈
--栈顶--
1
--栈底--
2进栈
--栈顶--
2
1
--栈底--
+操作符,二元操作,
栈顶两个元2,1出栈,
--栈顶--
--栈底--
运算得到3,进栈
--栈顶--
3
--栈底--
4进栈
--栈顶--
4
3
--栈底--
*操作符,二元操作,
栈顶两个元4,3出栈,
--栈顶--
--栈底--
运算得到12,进栈
--栈顶--
12
--栈底--
http://bbs.chinaunix.net/thread-316197-1-1.html
本版有几个,这是我有印象的一个,供参考。
dc就维系着这样的一个栈,我们可以称为主栈(实际上,dc可以维系很多很多这样的崭,可只有这一个栈直接用于运算,所以我们可以称为主栈,其他可以用来存储)。
我们来运行比如
echo '1 2+p' | dc
可以打印出3,相邻两个进栈的操作数用空格或者空行隔开,p是dc的命令,代表打印栈顶
当然我们也可以运行更复杂的
echo '1 2+4*p' | dc
12
如果仅仅是这样,dc看上去就太简单了。
dc的强大之处是在于它可以用于编程。
btw:echo '2p3p[dl!d2+s!%0=@l!l^!<#]s#[s/0ds^]s@[p]s&[ddvs^3s!l#x0<&2+l.x]ds.x'|dc
很强
最先介绍的还是运算符:
+二元运算, 弹出栈顶两个元,计算和,再压栈
- 二元运算,弹出栈顶元a,再弹出栈顶元b,计算b-a,压栈
*二元运算,弹出栈顶两个元,计算积,再压栈
/二元运算,弹出栈顶元a,再弹出栈顶元b,计算b/a,保留预定的位数的有效小数,压栈
%二元运算,弹出栈顶元a,再弹出栈顶元b,计算b%a(余数),压栈
~二元运算,同时计算余数和商(GNU扩展)
^二元运算,乘方计算弹出栈顶元a,再弹出栈顶元b,计算a的b次方压栈,计算时,b忽略小数部分
v一元运算,求平方根,弹出栈顶元a,计算平方根,保留预定的位数的有效小数,压栈
注:有效小数保留预定位数,后面有介绍。
用于打印的命令:
p 打印栈顶信息,并换行
n 打印栈顶信息,不换行,并且栈顶出栈(GNU扩展)
P 打印栈顶,不换行,并且栈顶出栈。打印方式本应与GNU扩展的n一致,但对于数字则有GNU扩展,打印出其整数部分的绝对值除以256所得到的字符。
f 打印出整个栈
这里提供了dc程序本身的所有输出方式(除了还有一个!命令可以用来执行外部命令)
之后的一些命令与介绍就与实现复杂程序的结构有关系了。
c 清空栈
d 将栈顶复制一份进栈,举个例子,比如2d*就是代表2的乘方了
r 将栈最顶上两个元位置交换(GNU扩展)
但以下会介绍寄存器,d,r都可以用的别的方式实现,算语法糖了
比如d
如果某个寄存器,比如名字叫a,在程序中不作它用,那么
salala就可以实现d , sa是先将栈顶出栈,放在寄存器a,然后连续从a读两次进栈
如果某两个寄存器不作它用,比如a和b,那么
sasblalb就可以实现r
本帖最后由 cjaizss 于 2011-04-16 21:36 编辑
该轮到寄存器出场了
所有的字符都可以做为独立的寄存器名称
a,b,c,d,1,2,3,4,A,B,C...
甚至,#@!%^&*()-+='"][{}||.~`.都可以
所以有很多很多寄存器可供使用,一共可以有256个之多,足够用了。
\xa0,\xa1...,\xff都是不同的寄存器
还记得d命令复制栈顶吗?f打印整个主栈?以下相当于1001 d f,使用了寄存器\xff
echo -e '1001 s\xff l\xff l\xff f' | dc
1001
1001
现在以寄存器r来代表
首先,我们要清楚,寄存器是一个栈结构,和主栈是一样的,只是它不能直接用于计算而已,是用于存储的,初始的时候也是空栈,
sr 将主栈栈顶出栈,如果寄存器r栈为空,则将刚才出主栈的值入r栈,否则修改r栈顶为刚才出主栈的值
lr 将寄存器r栈顶的值入主栈,为空则会打印错误信息(说到这里,其实dc里面所有操作栈出错都会打印错误信息,并跳过)
Sr 将主栈栈顶出栈,r栈进栈
Lr r栈出栈,主栈进栈
要理解下面两个命令,就要先明白寄存器栈的每一层都可以有一个使用数字下标访问的数组
:r 主栈出栈两次,先从主栈栈顶弹出一个值a,再从主栈栈顶弹出一个值b,然后令r[a]=b
;r 主栈出栈,从主栈栈顶弹出一个值a,然后将r[a]进主栈