fbpx
维基百科

dc (程序)

dc(desk calculator:桌面计算器)是采用逆波兰表示法跨平台计算器,它支持任意精度算术[1]。它是Robert Morris英语Robert Morris (cryptographer)贝尔实验室期间书写的[2],作为最老的Unix实用工具,先于C语言的发明。像那个年代的其他实用工具一样,它有着一组强力的特征和简洁的语法[3][4]。传统上,采用中缀表示法bc计算器程序是在dc之上实现的。

历史

dc是幸存的最老的Unix语言[2]。在贝尔实验室收到第一台PDP-11的时候,用B语言写成的dc是在这个新机器上运行的第一个语言,甚至在汇编器之前[5]

基本操作

在dc中要做4和5的乘法:

$ dc 4 5 * p 20 q 

这可转译为“把4和5压入栈顶,通过乘法算符,从栈中弹出两个元素,将二者相乘并把结果压回栈顶”。接着使用p命令打印栈顶的元素。使用q命令退出此次调用的dc实例。注意数值相互间必须以空白分隔,但某些算符可以不必如此。 还可以用如下命令得到这个结果:

$ dc -e '4 5 * p' 20 $ echo "4 5 * p" |dc 20 $ dc - 4 5*pq 20 $ cat <<EOF > cal.txt 4 5 * p  EOF $ dc cal.txt 20 

使用命令k来变更算术精度,它设置算术运算的小数位数。因为缺省精度是0,例如:

$ dc -e "2 3 / p" 0 

通过使用命令k调整精度,可以产生任意数目的小数数位,例如:

$ dc -e "5 k 2 3 / p" .66666 

dc有科学计算器的基本运算功能,比如求 的值:

$ dc -e "2k 12 _3 4 ^ + 11 / v 22 - p" -19.10 

其中,_用于输入负数,^计算幂,v计算平方根。

使用d命令复制栈顶元素。使用r命令对栈顶和仅次栈顶的两个元素进行对换。使用z命令压入当前栈深度,即执行z命令前栈中元素的数目。

输入/输出

使用?命令,从stdin读取一行并执行它。这允许从宏中向用户要求输入,故而此输入必须是语法上正确的,并且这有潜在的安全问题,因为dc的!命令可以执行任意系统命令。

前面提及过,p命令打印栈顶元素,带有随后的一个换行。n命令弹出栈顶元素并输出它,没有尾随换行。f命令打印整个栈,一项一行。

dc还支持控制输入和输出的基数i命令弹出栈顶元素并将它用作输入基数。十六进制数字必须大写以避免和dc命令冲突,输入基数必须在2和16之间,输出基数必须大于等于2。o命令设置输出基数,要记住输入基数将影响对后面的所有数值的分析,所以通常建议先设置输出基数。例如将二进制转换成十六进制:

$ echo 16o2i 11011110101011011011111011101111p | dc DEADBEEF 

要读取设置的这些数值,KIO命令将压入当前精度、输入基数和输出基数到栈顶。

语言特征

除了上述的基本算术和栈操作,dc包括了对、条件和存储结果用于以后检索的支持。

寄存器

寄存器在dc中是有着单一字符名字的存贮位置,它可以通过命令来存储和检索,它是宏和条件的底层机制:sc弹出栈顶元素并将它存储入寄存器c,而lc将寄存器c的值压入栈顶。例如:

 3 sc 4 lc * p

寄存器还被当作次要栈,可以使用SL命令在它们和主要栈之间压入和弹出数值。存储栈顶元素到寄存器中并把这个元素留在栈顶,需要联合使用ds命令。

字符串

字符串是包围在[]之中的字符,可以被压入栈顶和存入寄存器。使用x命令从栈顶弹出字符串并执行它,使用P命令从栈顶弹出并打印字符串,无尾随换行。a命令可以把数值的低位字节转换成ASCII字符,或者在栈顶是字符串时把它替换为这个字符串的第一个字符。此外没有方法去建造字符串或进行字符串操纵。

#字符开始一个注释直到此行结束。

通过允许寄存器和栈项目像数值一样存储字符串,从而实现了。一个字符串可以被打印,也可以被执行,就是说作为dc命令的序列而传递。例如可以把一个宏“加1并接着乘以2”存储到一个寄存器m中:

 [1 + 2 *] sm

通过使用x命令弹出栈顶的字符串并执行之,如下这样使用存储的宏:

 3 lm x p

Q命令从栈顶弹出一个值作为退出宏的层数,比如2Q命令退出2层宏,它永不导致退出dc。q命令退出2层宏,如果宏少于2层则退出dc。

条件

最后提供了有条件执行宏的机制。命令=r将从栈顶弹出两个值,如果二者相等,则执行存储在寄存器r中的宏。如下命令序列将在原栈顶元素等于5的条件下打印字符串equal

[[equal]p] sm d 5 =m

这里使用了d命令保留原栈顶元素。其他条件有>!><!<!=,如果栈顶元素分别大于、不大于(小于等于)、小于、不小于(大于等于)、不等于仅次于栈顶的元素,则执行指定宏。

迭代

通过定义有条件的调用自身的递归宏,迭代也是可行的。一个简单的对栈顶元素的阶乘过程

 # F(x): return x! # if x-1 > 1 # return x * F(x-1) # otherwise # return x

可实现为:

 [d1-d1<F*]dsFxp

这里宏中的第一个d命令相当于分配了一个局部变量。

例子

Unix V7手册页举出的编程实例为打印阶乘n!的前10个值:

$ dc -e "[la1+dsa*pla10>y]sy 0sa1 lyx" 1 2 6 24 120 720 5040 40320 362880 3628800 

这个程序实现了For循环,将作为循环体的宏[la1+dsa*pla10>y]存储在寄存器y中;把寄存器a作为循环计数器,设其初始值为0,将0!的值1压入栈顶;从寄存器y中取出宏并执行之。宏中的la1+dsa将计数器a的数值加1,并将这个值留在栈顶;随后*p从栈中弹出两个元素进行乘法并把结果压入栈中,打印这个结果;随后la10>y将计数器a的数值和数值10压入栈中,判断位于栈顶的10是否大于计数器的数值,即计数器的数值是否小于10,弹出二者并在判断成立的条件下再次执行存储在寄存器y中的宏。计数器a的数值从0增加到10,宏一共被执行了10次。

参见

  • bc
  • 计算器输入方法英语Calculator input methods
  • 堆栈机器

引用

  1. ^ dc(1): an arbitrary precision calculator – Linux用户命令(User Commands)手册页
  2. ^ 2.0 2.1 Brian Kernighan and Ken Thompson. A nerdy delight for any Vintage Computer Fest 2019 attendee: Kernighan interviewing Thompson about Unix. YouTube. 事件发生在 29m45s. [September 3, 2019]. (原始内容于2022-02-01). 
  3. ^ The sources for the manual page for 7th Edition Unix dc. [2020-09-25]. (原始内容于2019-09-24). 
  4. ^ Ritchie, Dennis M. The Evolution of the Unix Timesharing System. Sep 1979 [2019-05-31]. (原始内容存档于2010-05-06). 
  5. ^ McIlroy, M. D. A Research Unix reader: annotated excerpts from the Programmer's Manual, 1971–1986 (PDF) (Technical report). CSTR. Bell Labs. 1987 [2019-05-31]. 139. (原始内容 (PDF)于2019-11-30). 

外部链接

程序, desk, calculator, 桌面计算器, 是采用逆波兰表示法的跨平台计算器, 它支持任意精度算术, 它是robert, morris, 英语, robert, morris, cryptographer, 在贝尔实验室期间书写的, 作为最老的unix实用工具, 先于c语言的发明, 像那个年代的其他实用工具一样, 它有着一组强力的特征和简洁的语法, 传统上, 采用中缀表示法的bc计算器程序是在dc之上实现的, dc原作者robert, morris, 英语, robert, morris, crypt. dc desk calculator 桌面计算器 是采用逆波兰表示法的跨平台计算器 它支持任意精度算术 1 它是Robert Morris 英语 Robert Morris cryptographer 在贝尔实验室期间书写的 2 作为最老的Unix实用工具 先于C语言的发明 像那个年代的其他实用工具一样 它有着一组强力的特征和简洁的语法 3 4 传统上 采用中缀表示法的bc计算器程序是在dc之上实现的 dc原作者Robert Morris 英语 Robert Morris cryptographer AT amp T贝尔实验室 開發者各种开源和商业开发者编程语言B操作系统Unix 类Unix Plan 9系統平台跨平台类型命令许可协议GNU通用公共许可证3 0版 目录 1 历史 2 基本操作 3 输入 输出 4 语言特征 4 1 寄存器 4 2 字符串 4 3 宏 4 4 条件 4 5 迭代 5 例子 6 参见 7 引用 8 外部链接历史 编辑dc是幸存的最老的Unix语言 2 在贝尔实验室收到第一台PDP 11的时候 用B语言写成的dc是在这个新机器上运行的第一个语言 甚至在汇编器之前 5 基本操作 编辑在dc中要做4和5的乘法 dc 4 5 p 20 q 这可转译为 把4和5压入栈顶 通过乘法算符 从栈中弹出两个元素 将二者相乘并把结果压回栈顶 接着使用p命令打印栈顶的元素 使用q命令退出此次调用的dc实例 注意数值相互间必须以空白分隔 但某些算符可以不必如此 还可以用如下命令得到这个结果 dc e 4 5 p 20 echo 4 5 p dc 20 dc 4 5 pq 20 cat lt lt EOF gt cal txt 4 5 p EOF dc cal txt 20 使用命令k来变更算术精度 它设置算术运算的小数位数 因为缺省精度是0 例如 dc e 2 3 p 0 通过使用命令k调整精度 可以产生任意数目的小数数位 例如 dc e 5 k 2 3 p 66666 dc有科学计算器的基本运算功能 比如求12 3 4 11 22 displaystyle sqrt 12 3 4 over 11 22 的值 dc e 2k 12 3 4 11 v 22 p 19 10 其中 用于输入负数 计算幂 v计算平方根 使用d命令复制栈顶元素 使用r命令对栈顶和仅次栈顶的两个元素进行对换 使用z命令压入当前栈深度 即执行z命令前栈中元素的数目 输入 输出 编辑使用 命令 从stdin读取一行并执行它 这允许从宏中向用户要求输入 故而此输入必须是语法上正确的 并且这有潜在的安全问题 因为dc的 命令可以执行任意系统命令 前面提及过 p命令打印栈顶元素 带有随后的一个换行 n命令弹出栈顶元素并输出它 没有尾随换行 f命令打印整个栈 一项一行 dc还支持控制输入和输出的基数 i命令弹出栈顶元素并将它用作输入基数 十六进制数字必须大写以避免和dc命令冲突 输入基数必须在2和16之间 输出基数必须大于等于2 o命令设置输出基数 要记住输入基数将影响对后面的所有数值的分析 所以通常建议先设置输出基数 例如将二进制转换成十六进制 echo 16o2i 11011110101011011011111011101111p dc DEADBEEF 要读取设置的这些数值 K I和O命令将压入当前精度 输入基数和输出基数到栈顶 语言特征 编辑除了上述的基本算术和栈操作 dc包括了对宏 条件和存储结果用于以后检索的支持 寄存器 编辑 寄存器在dc中是有着单一字符名字的存贮位置 它可以通过命令来存储和检索 它是宏和条件的底层机制 sc弹出栈顶元素并将它存储入寄存器c 而lc将寄存器c的值压入栈顶 例如 3 sc 4 lc p 寄存器还被当作次要栈 可以使用S和L命令在它们和主要栈之间压入和弹出数值 存储栈顶元素到寄存器中并把这个元素留在栈顶 需要联合使用ds命令 字符串 编辑 字符串是包围在 和 之中的字符 可以被压入栈顶和存入寄存器 使用x命令从栈顶弹出字符串并执行它 使用P命令从栈顶弹出并打印字符串 无尾随换行 a命令可以把数值的低位字节转换成ASCII字符 或者在栈顶是字符串时把它替换为这个字符串的第一个字符 此外没有方法去建造字符串或进行字符串操纵 字符开始一个注释直到此行结束 宏 编辑 通过允许寄存器和栈项目像数值一样存储字符串 从而实现了宏 一个字符串可以被打印 也可以被执行 就是说作为dc命令的序列而传递 例如可以把一个宏 加1并接着乘以2 存储到一个寄存器m中 1 2 sm 通过使用x命令弹出栈顶的字符串并执行之 如下这样使用存储的宏 3 lm x p Q命令从栈顶弹出一个值作为退出宏的层数 比如2Q命令退出2层宏 它永不导致退出dc q命令退出2层宏 如果宏少于2层则退出dc 条件 编辑 最后提供了有条件执行宏的机制 命令 r将从栈顶弹出两个值 如果二者相等 则执行存储在寄存器r中的宏 如下命令序列将在原栈顶元素等于5的条件下打印字符串equal equal p sm d 5 m 这里使用了d命令保留原栈顶元素 其他条件有 gt gt lt lt 如果栈顶元素分别大于 不大于 小于等于 小于 不小于 大于等于 不等于仅次于栈顶的元素 则执行指定宏 迭代 编辑 通过定义有条件的调用自身的递归宏 迭代也是可行的 一个简单的对栈顶元素的阶乘过程 F x return x if x 1 gt 1 return x F x 1 otherwise return x 可实现为 d1 d1 lt F dsFxp 这里宏中的第一个d命令相当于分配了一个局部变量 例子 编辑Unix V7手册页举出的编程实例为打印阶乘n 的前10个值 dc e la1 dsa pla10 gt y sy 0sa1 lyx 1 2 6 24 120 720 5040 40320 362880 3628800 这个程序实现了For循环 将作为循环体的宏 la1 dsa pla10 gt y 存储在寄存器y中 把寄存器a作为循环计数器 设其初始值为0 将0 的值1压入栈顶 从寄存器y中取出宏并执行之 宏中的la1 dsa将计数器a的数值加1 并将这个值留在栈顶 随后 p从栈中弹出两个元素进行乘法并把结果压入栈中 打印这个结果 随后la10 gt y将计数器a的数值和数值10压入栈中 判断位于栈顶的10是否大于计数器的数值 即计数器的数值是否小于10 弹出二者并在判断成立的条件下再次执行存储在寄存器y中的宏 计数器a的数值从0增加到10 宏一共被执行了10次 参见 编辑bc 计算器输入方法 英语 Calculator input methods 堆栈机器引用 编辑 dc 1 an arbitrary precision calculator Linux用户命令 User Commands 手册页 2 0 2 1 Brian Kernighan and Ken Thompson A nerdy delight for any Vintage Computer Fest 2019 attendee Kernighan interviewing Thompson about Unix YouTube 事件发生在 29m45s September 3 2019 原始内容存档于2022 02 01 The sources for the manual page for 7th Edition Unix dc 2020 09 25 原始内容存档于2019 09 24 Ritchie Dennis M The Evolution of the Unix Timesharing System Sep 1979 2019 05 31 原始内容存档于2010 05 06 McIlroy M D A Research Unix reader annotated excerpts from the Programmer s Manual 1971 1986 PDF Technical report CSTR Bell Labs 1987 2019 05 31 139 原始内容存档 PDF 于2019 11 30 外部链接 编辑软件包dc 页面存档备份 存于互联网档案馆 在Debian GNU Linux仓库中 bc的原生Windows移植包括了dc 嵌入到网页中的dc 页面存档备份 存于互联网档案馆 The unix dc 1 command this is the esoteric language that made it big 页面存档备份 存于互联网档案馆 取自 https zh wikipedia org w index php title Dc 程序 amp oldid 75985774, 维基百科,wiki,书籍,书籍,图书馆,

文章

,阅读,下载,免费,免费下载,mp3,视频,mp4,3gp, jpg,jpeg,gif,png,图片,音乐,歌曲,电影,书籍,游戏,游戏。