免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12345下一页
最近访问板块 发新帖
查看: 20686 | 回复: 40
打印 上一主题 下一主题

dc计算器简介 [复制链接]

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-04-16 18:29 |只看该作者 |倒序浏览
本帖最后由 cjaizss 于 2011-04-17 09:20 编辑

虽然没想明白这个东西有什么实际用处,bc完全可以用一种更可观的方式来代替dc.
但用来做做智力体操,还是有点意思的。
简介自四楼起

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
2 [报告]
发表于 2011-04-16 18:30 |只看该作者
不过想来也还是有实际用处,用来写脚本,有的时候产生逆波兰更容易一些

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
3 [报告]
发表于 2011-04-16 18:42 |只看该作者
好,偶写一个简单的dc教材吧。

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
4 [报告]
发表于 2011-04-16 18:53 |只看该作者
好,偶写一个简单的dc教材吧。
cjaizss 发表于 2011-04-16 18:42

首先,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
--栈底--

论坛徽章:
7
荣誉版主
日期:2011-11-23 16:44:17子鼠
日期:2014-07-24 15:38:07狮子座
日期:2014-07-24 11:00:54巨蟹座
日期:2014-07-21 19:03:10双子座
日期:2014-05-22 12:00:09卯兔
日期:2014-05-08 19:43:17卯兔
日期:2014-08-22 13:39:09
5 [报告]
发表于 2011-04-16 19:03 |只看该作者
http://bbs.chinaunix.net/thread-316197-1-1.html
本版有几个,这是我有印象的一个,供参考。

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
6 [报告]
发表于 2011-04-16 19:25 |只看该作者
首先,dc是一个计算器。但其操作习惯不同于我们常用的中缀式,而采用逆波兰式的方法。
所谓中缀式,即操 ...
cjaizss 发表于 2011-04-16 18:53



    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
很强

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
7 [报告]
发表于 2011-04-16 19:50 |只看该作者
dc就维系着这样的一个栈,我们可以称为主栈(实际上,dc可以维系很多很多这样的崭,可只有这一个 ...
cjaizss 发表于 2011-04-16 19:25



    最先介绍的还是运算符:
    +二元运算, 弹出栈顶两个元,计算和,再压栈
    - 二元运算,弹出栈顶元a,再弹出栈顶元b,计算b-a,压栈
    *二元运算,弹出栈顶两个元,计算积,再压栈
    /二元运算,弹出栈顶元a,再弹出栈顶元b,计算b/a,保留预定的位数的有效小数,压栈
  %二元运算,弹出栈顶元a,再弹出栈顶元b,计算b%a(余数),压栈
  ~二元运算,同时计算余数和商(GNU扩展)
   ^二元运算,乘方计算弹出栈顶元a,再弹出栈顶元b,计算a的b次方压栈,计算时,b忽略小数部分
  v一元运算,求平方根,弹出栈顶元a,计算平方根,保留预定的位数的有效小数,压栈
注:有效小数保留预定位数,后面有介绍。

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
8 [报告]
发表于 2011-04-16 20:16 |只看该作者
用于打印的命令:
p  打印栈顶信息,并换行
n  打印栈顶信息,不换行,并且栈顶出栈(GNU扩展)
P  打印栈顶,不换行,并且栈顶出栈。打印方式本应与GNU扩展的n一致,但对于数字则有GNU扩展,打印出其整数部分的绝对值除以256所得到的字符。
f  打印出整个栈
这里提供了dc程序本身的所有输出方式(除了还有一个!命令可以用来执行外部命令)

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
9 [报告]
发表于 2011-04-16 20:30 |只看该作者
之后的一些命令与介绍就与实现复杂程序的结构有关系了。
c  清空栈
d 将栈顶复制一份进栈,举个例子,比如2d*就是代表2的乘方了
r  将栈最顶上两个元位置交换(GNU扩展)

但以下会介绍寄存器,d,r都可以用的别的方式实现,算语法糖了
比如d
如果某个寄存器,比如名字叫a,在程序中不作它用,那么
salala就可以实现d , sa是先将栈顶出栈,放在寄存器a,然后连续从a读两次进栈
如果某两个寄存器不作它用,比如a和b,那么
sasblalb就可以实现r

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
10 [报告]
发表于 2011-04-16 21:16 |只看该作者
本帖最后由 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]进主栈
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP