数摞
汉编语言独有的概念
数摞,拼音为shù luò,是汉编语言独有的概念,它是在内存中开辟出的一个空间,它不仅是汉编程序运行中数据处理的场所,也是数据临时存储的场所,还是各模块间参数传递的场所。数摞结构的引入既统一了程序中各参数的临时存储场所和格式,也让程序员能够同步跟踪并调试程序的运行。而在C语言中所有这些工作只能交给编译器,一旦出现错误,调试工作只能从零开始。
数摞及运算方法
计算机中数的概念
汉语编程引入了数摞的概念,关于数摞我们应该从中国古老的算盘说起。
首先我们可以讲,中国人最早发明了数字计算机即算盘,算盘的表达方式与现代计算机的表达方式非常接近。
探寻人类数字化的起源,大概要从结绳记事开始,人们把打绳结记为“1”,而未打绳结记为“0”。为方便起见,我们将一段绳子看作算盘的一个杆,打绳结视为算盘珠拨在上面,反之拨在下面。这样就形成了一个二进制的算盘。
一个算盘珠只能表示两种状态,0或1,两个算盘珠可以表示4种状态;算盘珠全部拨下表示0,最右边的珠子单独拨上去表示1,左边的珠子单独拨上去表示2,两个算盘珠都拨上去则表示3。这四种状态分别表示为00,01,10,11。如果要表示更大的数则只有将算盘珠增多。三个算盘珠可以表示8种状态,那么按2的n次方的算法依次类推分别为:
16,32,64,128,256,512,1024,2048,4096,16384,32768,65536,……。
计算机内部数的大小与算盘同样有限,一般将其分为8位、16位、32位、64位等等。为了不至于将运算位取的太大,又能满足于实际应用的要求,对于较早的系统将16位作为一个运算的基本单位,而对于进来的windows系统一般将32位作为一个运算的基本单位。一个16位的数可以表示65536种状态,作为一个16位的正整数,可以从0~65535。但是作为一个有符号的数,则往往用16位最高位为1来表示这个数为负数,这时这个16位的数只能从-32768~+32767范围。而一个32位的数可以表示4294967295种状态, 作为一个32位的正整数,可以从0~4294967295。但是作为一个有符号的数,则往往用32位最高位为1来表示这个数为负数,这时这个32位的数只能从-2147483648~+2147483647范围。对于一个16位的系统其单精度是16位,而双精度是32位;对于一个32位的系统其单精度是32位,而双精度是64位。
上述一个二进制的数可以表达一定的数值范围,但它如何表达这个数的实际值呢?对于一个无符号数,我们可以按上述二进制的算盘记数的方法依次类推,对于16位数的每一种状态找到其从0~65535的对应值;而对于32位数的每一种状态找到其从0~4294967295的对应值。但对于有符号数来说就不能简单地套用这种办法。在有符号数的二进制表示中,我们分别引入原码、反码和补码三种概念。为了简单起见,我们以8位数来说明有符号数三种编码的表示方法。
带符号数的表示法
一个数可用其最高位来表示符号,正数的最高位为0,负数的最高位为1,其余位仍然按正常方法表示数值,这种表示方法叫做原码表示法。如:
原码表示简单易懂,而且与机器的真值转换方便。但若是两个异号数相加(或两个同号数相减)就要做减法。为了把上述运算转换为加法运算就引入了反码和补码的概念。
正数的反码表示与原码表示相同,最高位为符号位,用“0”表示正,其余位为数值位。如:
符号位 二进制数值
( +4) = 0 0 0 0 0 1 0 0
( +31) = 0 0 1 1 1 1 1 1
(+127) = 0 1 1 1 1 1 1 1
而负数的反码表示,即为它的正数的按位取反(含符号位)。
符号位 二进制数值
( +4) = 0 0 0 0 0 1 0 0
( - 4) = 1 1 1 1 1 0 1 1
( +31) = 0 0 0 1 1 1 1 1
( - 31) = 1 1 1 0 0 0 0 0
(+127) = 0 1 1 1 1 1 1 1
(- 127) = 1 0 0 0 0 0 0 0
( +0 ) = 0 0 0 0 0 0 0 0
( - 0 ) = 1 1 1 1 1 1 1 1
8位二进制数的反码表示有以下特点:
1. “0”有两种表示法。
2. 8位二进制反码所能表示的数值范围为+127~ -128。
3. 当一个有符号数用反码表示时,最高位为符号位。当符号位为“0”(即正数)时,后面的七位为数值部分;但当符号位为“1”(即负数)时,后面几位表示的不是此负数的数值,一定要把它们按位取反,才表示它的二进制值。
二进制表示的另一种方式为补码方式。正数的补码表示与原码表示相同,即最高位为符号位,用“0”表示正,其余位为数值位。如:
符号位 二进制数值
( +4) = 0 0 0 0 0 1 0 0
( +31) = 0 0 1 1 1 1 1 1
(+127) = 0 1 1 1 1 1 1 1
而负数的补码表示即为它的反码,且在最后位(即最低位)加1。如:
符号位 二进制数值
( +4) = 0 0 0 0 0 1 0 0 原码
( - 4) = 1 1 1 1 1 0 1 1 反码
( - 4) = 1 1 1 1 1 1 0 0 补码
( +31) = 0 0 0 1 1 1 1 1 原码
( - 31) = 1 1 1 0 0 0 0 0 反码
( - 31) = 1 1 1 0 0 0 0 1 补码
(+ 127) = 0 1 1 1 1 1 1 1 原码
(- 127) = 1 0 0 0 0 0 0 0 反码
(- 127) = 1 0 0 0 0 0 0 1 补码
( +0 ) = 0 0 0 0 0 0 0 0 原码
( - 0 ) = 1 1 1 1 1 1 1 1 反码
( - 0 ) = 1 0 0 0 0 0 0 0 补码
8位带符号的补码表示有以下特点:
1.(+0)= (- 0)= 00000000
2. 8位二进制补码所能表示的数值为:+127~-128
3. 一个用补码表示的二进制数,最高位为符号位,当符号位“(即正数)时,其余七位即为此数的二进制值;但当符号位“1”(即负数)时,其余几位不是此数的二进制值,把它们按位取反,且在最低位加1,才是它的二进制值。当负数采用补码时,就可以把减法转换成加法。例如:
64 –10 =64+(-10)=64+[10]补
+64=01000000
10=00001010
[-10]补=11110110
于是
0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0
- 0 0 0 0 1 0 1 0 + 1 1 1 1 0 1 1 0
———————— ————————
0 0 1 1 0 1 1 0 [ 1] 0 0 1 1 0 1 1 0
自然丢失
一个算盘的位数是有限制的,在做运算时最高位将自行丢失,故做减法与补码相加的结果是相同的。同样我们可以将这种表示法扩展到16位以至32位。计算机中在许多情况下都是用二进制补码的方式表示数值的。汉语编程语言在大部分情况下也用二进制补码表示数值。
补码的巧妙应用使计算机中的加法与减法一致,这无疑在简化计算方法,提高计算机运行效率起了很大的作用。
如果把每个小算盘看作一位数,那么它能表示数的范围是0~15。在我们习惯的十进制表示法中一位数字只能表示0~9,从10开始需用两位以上的数字表示。若想用一位数来表示十以上的数字,则可利用那些最常用的、使用最方便的字符。在十六种状态中,零至九仍用阿拉伯数字0~9表示,而十至十五则用英文字母A~F表示,这就是十六进制表示法。这样上面的每一个小算盘的十六进制表示法就是:
从单独一个小算盘很容易看出十六进制与二进制的对应关系。巧妙的是四位二进制数正好是一位十六进制数。这样在识别一个十六进制数代表的二进制状态时,可以按位四位一组进行二进制变换,且变换过程中不会象十进制转换为二进制那样,转换一位而影响其他位。
为了便于理解我们将一个四位小算盘三种数制的对应关系列出:
以后进行二进制与十六进制之间的互相转换,可以根据上面算盘的对应关系来完成。但要进行多位的十进制转换则必须进行计算。
有趣的是中国传统的算盘不仅可以进行十进制计算,同时还可很方便的完成十六进制计算。下面把传统算盘的十六进制表示法列出供大家思考。
算盘的一排珠子可以表示从0~15,即十六进制的一位,也是中国传统十六两制的一位,可见成语中“半斤八两”表示的是二者相等,而不是差不多。
我们可以把一根算盘杆看作为计算机的四位,而两根算盘杆看作为计算机中的八位,专业术语称为“字节”,当以后分析计算机数据结构时你可以将两根算盘杆想象为一个字节。那么上面的算盘正好是计算机中一个64位数。
汉语编程为了提高运算速度、优化结构、方便记忆,借鉴中国古代数学算筹的思想,采用了“数摞” 这一特殊方式,将参与运算的数据如同一个个算筹或算盘在计算机内存中有序地摞起来。在运算过程中,自动把摞顶层参与运算的数据删除,并将运算结果重新放回到顶层。这种累加器总是在顶端寄存器的操作方式,实践了无限寄存器这一新的计算机理论。数摞是汉语程序设计语言中的一个重要方式,,本章将着重介绍其具体操作及与之密切相关的算术运算和逻辑运算。
数摞的概念及表示方法
数摞是汉编程序中独有的概念,它是在内存中开辟出的一个空间,它不仅是汉编程序运行中数据处理的场所,也是数据临时存储的场所,还是各模块间参数传递的场所。数摞结构的引入既统一了程序中各参数的临时存储场所和格式,也让程序员能够同步跟踪并调试程序的运行。而在C语言中所有这些工作只能交给编译器,一旦出现错误,调试工作只能从零开始。
你可以把计算机想象为一个机械的计算员,当它进行计算时仅有我们上面提到的算盘,而没有纸和笔。在进行大量的数据运算时,为了提高计算速度和便于记忆,最好的办法就是将算盘有序摆放,比如将算盘摞起来。为了保证在一定的空间可以放足够多的算盘,就将参加运算的数据以及结果的算盘都摞放起来。每次总是将参与计算的算盘拿走然后再将表示结果的算盘摞在顶层。例如进行一个最简单的加法运算3+4,我们先将表示3的算盘摞在顶上:
3
横线表示底线,在3和底线之间可能还有以前摞上去的算盘。然后再将表示4的算盘摞在顶上:
4
3
有了两个数后就可以做加法运算,其结果为7。这时参与运算的3和4已经没有用处就将它们移去,再把结果的7摞在顶上。
7
并非只有用移动盘的方法才能解决问题,而修改每个算盘中的内容更简便易行。在计算机内实际也只是修改相应内存的数值,而不能把这些内存地址搬来搬去。为了便于表达,我们称这个摞数的地方为“数摞”。数摞在表示数的时候,总是将最后输入的数放在数摞顶层,而前面输入的数向下顺移。有了数摞的概念,以后我们都按上面的这种方法来进行所有的计算。计算机的运算往往是连续的,前面计算的结果可能是后面运算所需要的参数。如计算(3+4)*5则按上面的方法先将3摞在数摞顶上,再将4摞在数摞顶上:
4
3
做完加法后将4和3去掉,并将7摞在数摞顶上:
7
然后再将5摞在数摞顶上:
5
7
最后做完乘法后将5和7去掉,将乘法的结果35摞在数摞的顶上:
35
我们刚才计算的是(3+4)*5,但是操作的顺序却没有按这个式子进行,而是3 4 + 5 * 。这种表示并不奇怪,无论做什么样的计算首先应该有被计算的数据,用(3+4)*5只是一种习惯,叫做中缀表示法。而用3 4 + 5 * 的表示方法叫做后缀表示法,即将运算符号放在参与运算的两个数的后面。采用后缀表示法也是一个习惯问题,它可以省去代表许多优先级的符号,更符合人类统筹安排事务的行为方式,比如在建筑过程中,我们总是首先设计好图纸,准备好建材,最后才开始施工。汉语正是使用这种表达方式,把中国古代数学文明与现代计算机编程技术巧妙地结合在一体。
汉语程序设计始终利用数摞来完成常规的运算,所以我们必须弄懂数摞的概念,并熟练地运用于程序设计之中。
数摞操作
一个人说话是要表达自己的意图,为了达到这一目的,在说话时可能会参杂许多不可缺少的“废话”,舍此,这段话可能就“不像话”了。程序设计也是如此,如汇编语言中要频繁的保护寄存器,高级语言中却要不断的进行变量操作。在汉语编程语言中,出现最多的“废话”就是数摞操作,然而正由于这些“废话”才使我们的程序设计变得更为精巧和生动。
在标准的汉语程序设计中所建立的数摞均以32位为基本单元。我们可以将一层想象成为一个具有32个杆和珠的算盘,每一个数都是由这种32位为基本单位的算盘来表示的。汉语编程操作与运算过程中的数据都是从数摞上取得,而操作结果也将放在数摞的顶上。这样显然带来一个问题,有的时候操作的结果并不一定是后面操作所需要的操作数,或者即使是操作数,但按后面操作的要求其顺序不对,或者后续的操作只需要部分的结果,使得我们不得不将数摞上的数据进行必要的调整以及复制。在汉语编程语言中提供了一系列的数摞操作算符,以便在程序设计中对数摞上的数据进行适当的调整。
数摞操作是汉语程序设计中最有趣,最巧妙的一个环节,使用极为频繁,读者一旦熟练掌握,到那时就可随心所欲编写汉语编程了。
数摞的交换
现在你来充当计算操作员,计算过程由指令员来指挥。指令员要做一个算术运算20-3*4,按照算术运算的优先规律应该先乘除后加减。所以指令员先将两个要相乘的数告诉你,由你按顺序将这两个数放入数摞:
4
3
接下来指令员又发出乘法指令,你计算出3 *4的结果,并将数摞上的3和4去掉,然后将结果12放入数摞:
12
指令员又将20告诉你,你随即将20放入数摞:
20
12
这时如果指令员发出减法的指令就出现问题了,因为减法没有交换规律,按规律必须是前面的数减去后面的数。在我们数摞上前面的数就是先进入的数,如果直接进行减法操作,就变成了12-20,为了解决这类问题,引入了一些数摞操作符。象上面的减法问题只要将两个数进行一次交换再执行减法就可以了。我们用符号“↑↓”表示交换操作。这样指令员在发出减法指令以前就必须发出“↑↓”指令,你就将数摞上数据的顺序交换一下,变成:
12
20
然后指令员再发出减法指令,你在做完减法后就可以将12和20去除,并将计算结果8放入数摞:
8
这个过程用汉语编程语言可以表述下面的形式:
3 4 * 20 ↑↓ -
以上只是为了说明问题举了一个例子,当然对于这样一种简单的计算完全可以写成另一种简化的形式
20 3 4 * -
我们放物品并不一定都是竖向摞置,有时要横向码放,如书架上的书基本上是横向码放的。为了表达方便,我们在表示数摞时常常也用横向方式来表示数摞里的状态。我们写文章时习惯从左至右,如果写的是数就进入数摞保存起来,先进入数摞的就在左边而后进入的就在右面。用横向法表示数摞时则记忆为右边的数在上,左边的数在下。如1 2 3 则表示为:
3
2
1
为了表达方便,我们还引入了数摞操作表述符号“―――”,并将操作前的数摞状态写在“―――”的左边,操作后的数摞状态写在右边,规范的写法应该为三个“―”,请读者养成良好的习惯。数摞上的数可以是一些代号,如“n1”、“n2”等等。如上面的“↑↓”操作,就表示为:
↑↓ ( n1 n2 ―――n2 n1 )
它代表
n1 n2 ↑↓ n2 n1
而对于“+”操作就表示为:
+ ( n1 n2 ―――n3 )
其中n3是n1与 n2之和。
了解了以上的基础知识,就可以进行数摞操作的练习了。在汉语编程系统中,系统提示符为“★”,表示操作的结束。在提示符“★”下的光标处就可以直接输入数值,并通过一些数摞的显示操作去查看数摞,如:
1 2 3 ★…
上面的描述中“<回车>”是指从键盘上键入[←┘Enter]键。提示符“★”后面有几个点“.”就表示当前数摞有多少个数。下面执行“看数摞”命令:
看数摞 [3]1 2 3 ★…
“看数摞”命令能显示当前数摞上仍保留的数。“[3 ]”表示当前数摞上有三个数。
+ ★..
看数摞 [2] 1 5 ★..
↑↓ ★..
看数摞[2] 5 1 ★..
需要注意的是,数摞交换操作符“↑↓”只对数摞顶项和次顶项进行交换操作。我们在数摞上再加一个数,然后执行交换操作:
2 ★…
看数摞 [3] 5 1 2 ★…
↑↓ ★…
看数摞 [3] 5 2 1 ★…
数摞的复制
许多情况下为了保证参加操作的数据仍然保留在数摞上,我们有必要对数摞上的数进行复制。在汉语编程中,对数摞进行复制的操作符是“♂”,其功能是对数摞顶层的数进行复制并将复制的数放在数摞顶层。
看数摞 [3] 5 2 1 ★…
♂★....
看数摞 [4] 5 2 1 1★....
操作符“♂”比较形象,圆圈代表数,向上的箭头代表向顶上复制,执行“♂”操作后的数摞状态为:
♂ ( n ―――n n )
“♂”的用途比较广,下面还是用“平方”的例子加以说明:
编 平方 ♂ * 。
该程序的运行体为“♂ *”。执行程序前,我们先给出一个参数n,当程序执行时,先复制一个n,将两个n相乘,即得到n的平方的结果。
复制次摞层
次摞层是从数摞顶层向下第二层,也是数摞第1项(以0基计算,数摞顶层为第0项,次摞层为第1项,依此类推)。次摞层的复制采用“∽”操作符:
看数摞 [3] 5 3 1 ★…
∽★....
看数摞 [4] 5 3 1 3 ★....
该例将数摞第1项3复制到数摞顶层作为第0项。
执行“∽”操作时数摞的状态为:
∽ ( n1 n2 ―――n1 n2 n1 )
横向比较法来看该符号,此图形好象绕过了摞顶的数而复制了第二项数据。
复制任意项
当我们需要对数摞上的任意一项进行复制时,可采用“§”操作符。使用该操作符时需指定参数,即指明将第几项复制到数摞顶层。
看数摞 [4] 5 3 1 3 ★....
2 § ★.....
看数摞 [5] 5 3 1 3 3 ★.....
该例将数摞的第2项(即3)复制到数摞顶层作为第0项。
使用该操作符同样需注意,前面的参数表示数摞的项数,这个项数同样以0基方式计算,如2表示数摞的第二项,即数摞从上往下第三层。
技巧:参照“♂”、“∽”可知:
0 § 等价于 ♂ ;1 § 等价于 ∽
数摞的旋转
在汉语编程过程中,有时需要将数摞上的三个数进行轮转,即将第三层的数放到数摞顶上,并将其他两个数向下顺移。这时我们采用“∴”操作符:
看数摞 [5] 5 3 1 2 4 ★.....
∴★.....
看数摞 [5] 5 3 2 4 1 ★.....
清屏后可以再举一例:
1 2 3 ★...
看数摞[3]1 2 3 ★...
∴★...
看数摞[3]2 3 1 ★...
执行“∴”操作时的数摞状态为:
∴ ( n1 n2 n3―――n2 n3 n1 )
反向旋转摞顶三项
有了数摞旋转的概念,就很容易理解数摞的反向旋转。它是将数摞顶层的数放到数摞第三层,并将原来第二层和第三层的数向上顺移。这时我们采用“∵”操作符:
看数摞 [5] 5 3 1 2 4 ★.....
∵★.....
看数摞 [5] 5 3 4 1 2 ★.....
清屏后可以再举一例:
1 2 3 ★...
看数摞[3]1 2 3 ★...
∵★...
看数摞[3]3 1 2 ★...
执行“∵”操作时的数摞状态为:
∵ ( n1 n2 n3―――n3 n1 n2 )
剔出任意项
虽然我们可以复制数摞上的任意项,但有时还有必要只将数摞上的任意项剔出来放在数摞的顶上。这时我们可以采用“√”操作:
看数摞[2]2 3 ★..
4 5 ★....
看数摞 [4]2 3 4 5 ★....
1 √ ★....
看数摞[4]2 3 5 4 ★....
2 √★....
看数摞 [4]2 5 4 3 ★....
3 √★....
看数摞 [4]5 4 3 2 ★....
执行“√”操作时的数摞状态为:
√ ( nn……n1 n0 n ―――nn-1 ……n1 n0 nn )
技巧:参照“∴”知:
2 √ 等价于 ∴
0 √ 是空操作
去除操作
在程序设计过程中,数摞上的有些数我们并不需要,为了不影响以下的操作,不得不将其删除。这时可以采用“♀”操作符:
看数摞[3]2 3 1 ★...
♀★..
看数摞[2]2 3 ★..
该例使用去除操作符将数摞顶层的数删除。
注意,该操作符只能删除当前数摞顶层即第0项的数。
执行“♀”操作时的数摞状态为:
♀ ( n ――― )
双精度数摞操作
双精度数摞操作是把普通数摞的两层当作一个整体来处理,操作方式与单层基本相同,主要包括内容有:双↑↓、双♂、双∽、双♀ 。
汉语编程运算方法
前几节我们主要对汉语程设计语言做了基本的介绍,并从实用的角度介绍了一些基本的操作,对于算术运算只是从应用的角度简单地做了尝试。本节我们将着重地讨论汉语程序设计语言的算术运算和逻辑运算。
算术运算
对于算术运算,我们从数的加减运算、乘除运算和浮点运算三个方面来讲述。
甲、数的加减运算
说到加、减、乘、除运算,大家肯定认为小学就学过加、减、乘、除,没必要再学了。其实编写计算机程序用到的主要还是古老的算术知识,高中、大学学到的许多高等数学知识不能被计算机直接解析。汉语程序设计语言的加、减、乘、除运算都是将数摞上的两个32位的数进行运算,同时“吃掉”参与运算的两个顶层数,将运算的结果放回数摞的顶层。
这样的运算只能对有符号数-2~+2-1(-2147483648~2147483647)之间的数进行运算,且运算结果也不能小于-2147483648和大于2147483647。一般情况下这个范围内的数是够用了,那如果不够用怎么办呢?在汉语程序设计语言中,各种运算和操作都是通过数摞进行的,数摞的每一层为一个32位的数,要表示更大的数可以有数摞的多层来表示。如果用数摞上的两层来表示一个数,我们就称这个数为双精度数,一个双精度数表示有符号数的范围就为:-2~+2-1。
对用数摞上的两层来表示的数,不能简单的用“+”、“-”来完成,而应用“双+”、“双-”来完成,且运算结果也占数摞的两层。下面是加减运算实际操作实例:
2 8 <回车>★.. (注:向数摞放了两个数:2和8)
看数摞<回车> [2] 2 8 ★.. (注:用“看数摞”查看数摞的状态)
+ 看数摞<回车> [1] 10 ★. (注:经过“+”运算后数摞的状态)
说明:最后数摞上的“10”就是“2+8”的结果。经过“+”运算后,将数摞上的“2和8”去掉,留下结果“10”。加法运算的数摞状态为:
+ ( n1 n2 --- n3 )
11<回车>★.. (注:继续向数摞放进一个数11)
看数摞<回车>[2] 10 11★..
- 看数摞<回车>[1] –1★.
说明:最后数摞上的“-1”就是“10-11”的结果。经过“-”运算后,将数摞上的“10”和“11”去掉,留下结果“-1”。减法运算的数摞状态为:
- ( n1 n2 --- n1 - n2 )
10 9 1 5 <回车>★....
看数摞<回车> [4] 10 9 1 5 ★....
双+ 看数摞<回车> [2] 11 14 ★..(注:经过“双+”后数摞上留下的运算结果)
10 <回车>★...
看数摞<回车> [3] 11 14 10 ★...
双+ 看数摞<回车> [1] 21 ★. (注:将10和11相加,丢失14)
3<回车>★..
看数摞<回车> [2] 21 3 ★..
双+ 看数摞<回车> 数摞已空!★
3 6 9 5 8 15<回车>★......
看数摞<回车> [6] 3 6 9 5 8 15 ★......
双+ 看数摞<回车> [4] 3 6 17 20 ★....
由该例可知,“双+”运算是对数摞顶上的4个数进行交叉运算,如果对两个数进行“双+”运算,则数摞为空;如果数摞上只有三个数,只能对第0项和第二项进行相加运算,而丢掉第一项;如果数摞上的数多于4个,则只对摞顶4个数进行交叉运算,其它的数不进行运算。双+数摞状态为:
双+ ( d1 d2 --- d3 )
同样道理,我们也可以进行“双-”运算,大家可以自己练习,这里不再赘述。
乙、数的乘除运算
汉语编程中有符号数的乘法运算与加法运算相同,操作前数摞上有两个有符号数,当执行完“*”后,参与运算的数摞被“吃掉”,留下两个数相乘的积。如:
2 8 <回车>★.. (注:向数摞放进两个数:2、8)
看数摞<回车> [2] 2 8 ★.. (注:用“看数摞”查看数摞上的状态)
* 看数摞<回车> [1] 16 ★. (注:经过“*”运算后数摞上的的状态)
说明:最后数摞上的“16”就是“2*8”的结果。经过“*”运算后,将数摞上的“2”和“8”去掉,留下结果“16”。乘法运算的数摞状态为:
* ( n1 n2 --- n3 )
n3是n1与n2的乘积,n3是32位,如果n1与n2的乘积超出-2147483648~2147483647的范围,其结果不可预测。由于在-2147483648~2147483647范围内的数已经足够使用,因此不用考虑数据溢出的问题。
除法与乘法是相对应的,汉语编程语言中的除法操作也会遇到有符号和无符号、单精度和双精度以及混合运算等问题。另外在除法运算时还存在商数的取整问题。在汉语编程中为方便计算机的运算,采用了向下取整的方法。如按向下取整的方法做
-7÷4=-2 余 +1
而用向零取整的方法得出上面的结果后还必须加1才对,在整数运算中采用了向下取整,则应考虑余数的符号必须与除数相同。总之应该为:
商*除数+余数=被除数
以上是整数运算中需要了解的基本知识,在汉语程序设计语言的程序设计中可以通过各种除法运算词来完成不同类型的除法运算。如:
/ ( n1 n2 ――― <商> )
数摞上留下n1除以n2的带符号32位的下整商。
求余数 ( n1 n2 ――― <余数> )
数摞上留下n1除以n2的余数,余数具有与n2相同的符号或者为零。
/余商 ( n1 n2 ――― <余数> <商> )
数摞上留下n1除以n2的余数和带符号的下整商。余数取除数的符号或为零。
丙、浮点数运算
汉语程序设计语言整合了浮点数、整数的处理的问题。所谓浮点数也是计算机采用的一种表示法,它把一个数的整数部分和小数部分分开表示。
采用浮点数表示法有很多的优点。在相同设备的情况下,浮点数能表示数的范围比定点数表示法要大,给程序设计带来方便;浮点计算中的数若采用规格化表示,则其精度较高,相对误差有限;由于能表示的数的范围很大,一般来说可以不必担心“溢出”问题。
汉语编程中的浮点数运算也就是将两个浮点数进行加、减、乘、除运算,运算后,按五舍六入的法则将小数点后按预先的定义保留若干位小数。定义小数位的格式为:n 位小数,如在汉语编程编译器下进行下列运算:
2.2 8.5<回车> ★.. (注:向数摞放了两个数:2.2 8.5)
+ 显<回车> [1] 10.70 ★ (注:经过“+”运算后,用“显”这个词显示运算的结果“10.70”并将结果删除 )
3 位小数<回车>★ (注:定义需要保留的小数的位数)
2.523 3.412 <回车>★..
+ 显<回车> [1] 5.935 ★
4 位小数<回车>★
8.599 2.314 <回车>★..
- 显<回车> [1] 6.2850 ★
汉语编程浮点运算在保留小数位时要遒循五舍六入的规则,这与我们习惯的四舍五入不同,要注意区别对待。如进行如下运算:
4 位小数<回车>★
2.03695 0.12362 + 显<回车>2.1606★
3.22236 2.98756 * 显<回车>9.6270★
总之,汉语编程中的算术运算与通常的数学算术运算基本一样,所不同的是它参与运算的数必须是同一类型,且是通过数摞来进行运算。
逻辑运算
逻辑运算要比算术运算简单的多,因为其参与运算的数和运算结果按位来看都只有两种状态:0和1。在这里0和1不是表示具体的数值,而表示两种不同的逻辑状态(一般用0表示假,1表示真),逻辑运算中的最基本的运算有三种,即与、或、非三种,也叫逻辑乘、逻辑加、逻辑求反。
甲、 逻辑乘法 (与)
逻辑乘法运算就是将两个基本命题用“与”这个系统词连接起来构成一个复合命题。
如基本命题:
一个星期有七天
一天有二十四小时
用“与”连接起来的复合命题:
一个星期有七天 与 一天有二十四小时
由这样的复合命题得出的结果(逻辑积),仍然是命题,重要的一点是要搞清逻辑积的真假是怎样由命题的真假来决定。总结逻辑乘法(与)的运算规则如下:
1.如果两个基本命题都是假的,它们的逻辑积也是假的。如:
3比2小 与 3比5大。
很明显“3比2小”是假的,“3比5大”也是假的,所以逻辑积也是假的。
2.两个基本命题中有一个是假的,则逻辑积也是假的。如:
3比2大 与 3比5大
“3比2大”是真的,“3比5大”是假的,所以逻辑积也是假的。
3.两个基本命题都是真的,则逻辑积也是真的。如:
3比2大 与 3比5小
“3比2大”是真的,“3比5大”也是真的,因此逻辑积也是真的。
如果用A和B表示两个基本命题,可以将逻辑积写成AB(也可写成AΛB或A·B)总结以上三点,可以将其列成一个表。如下:
我们一般把这个表叫做命题A、B的真值表。总结这个表,可以得出逻辑乘法运算规则是:有一命题为假逻辑积则为假,全部命题为真时逻辑积才为真。
乙、逻辑加法 (或)
逻辑加法运算就是将两个基本命题用“或”连接起来构成复合命题。由这样的复合命题得出的结果就是逻辑和,逻辑和的值为“0”或“1”,全由组成这个复合命题的基本命题来决定,总结逻辑加法(或)运算的运算规则如下:
1.两个基本命题都为假,则逻辑和也为假。如:
9小于5 或 9小于1
由“9小于5”和“9小于1”都是假命题,所也逻辑积就为假。
2.两个基本命题有一为真,则逻辑和就为真。
3.两个基本命题都为真,则逻辑和也为真。
若用A和B表示两个基本命题,总结以上三点可以得出逻辑和(A+B)的真值表如下:
丙、逻辑求反运算 (非)
逻辑求反运算就是将一个基本命题用“非”这个系统词连接起来组成复合命题。逻辑求反运算的结果完全由这一个基本命题来决定。由于是“求反”运算,所以很显然也看出,如要基本命题为真,则结果就应为假,如果基本命题为假,求反后,结果就应为真。
若用A表示这个基本命题,求反后的结果就应表示为_A,则逻辑求反运算的真值表可表示为:
丁、逻辑表达式
逻辑表达式就是用与、或、非等符号将基本命题连接起来的复杂的复合命题。如果用A、B、C分别表示三个基本命题,则(A+B)·C就是一个逻辑表达表,其意义是:A和B相或,结果再和C与。因此表达式(A+B)·C也可以表示为:(A或B)与C。其运算规则仍然遵循与、或、非的运算规则,其运算结果仍只有两种“0”或“1”。
若在同一逻辑表达表中同时有“与”运算、“或”运算和“非”运算,则按先“非”,后“与”,再“或”的规则省去括号。如“(AB)+(CD)”可写成“AB+CD”,而“(A+B)·(C+D)”不能写成“A+B·C+D”。
逻辑表达式的基本类型有以下几种:
1.“与或”表达式 在这种表达式中,各项以“与或”形式出现。
例如: F=AB+CD
2.“或与”表达式 在这种表达式中,各项以“或与”形式出现。
例如: F=(A+B)(C+D)
3.“与非”表达式 在这种表达式中,各项以“与非”形式出现。
例如:
4.“或非”表达式 在这种表达式中,各项均以“或非”形式出现。
例如:
5.“与或非”表达式 在这种表达式中,各项均以“与或非”形式出现。
例如:
总之,一个逻辑表达式有很多种形式,也可能很复杂。因此,通常要对逻辑表达式进行简化以取得最简表达形式。
汉语编程中的逻辑运算
有了以上的逻辑学的基础知识,接下来我们讨论汉语程序设计语言的逻辑运算。在汉语编程中我们可以用定义词来建立命题。如在汉语编程编辑器中定义如下内容:
编 真 1 。
编 假 0 。
编 3比5大 假 。
编 3比2小 假 。
编 3比2大 真 。
编 3比5小 真 。
编辑完后保存为“C:\u903b辑运算.chp”,然后打开汉语编程编译器装载该程序。装载完成后,可以在汉语编程系统下进行逻辑“与”操作。
3比5大 3比2小 与★.
显 0 ★
汉语编程逻辑运算与加、减、乘、除运算一样采用后缀表示法来表示。该例说明两个假命题相与的结果为假。
3比5大 3比2大 与★.
显 0 ★
结果说明一个假命题、一个真命题相与结果也为假。
3比5小 3比2大 与★.
显 1 ★
结果说明两个真命题相与其结果为真。
进行完“与”操作后,我们再利用刚才所编的程序来进行逻辑“或”运算。同样需要装载“逻辑运算.chp”这个程序,若刚才装载后还没有退出汉语编程系统,就不需要再装载了。
3比5大 3比2小 或★.
显 0 ★
结果说明两个假命题相或的结果为假。
3比5小 3比2小 或★.
显 1 ★
结果说明一真一假两个命题相或的结果为真。
3比5小 3比2大 或★
显 1 ★
结果说明两个真命题相或的结果为真。
进行完“与”和“或”的逻辑运算,我们再来看一下逻辑“非”的运算。同样在装载了“逻辑运算.chp”的情况下:
3比5大 非★.
显 -1 ★
结果说明假命题经过“非”运算后,其结果为真。
3比2大 非★.
显 -2 ★
结果说明真命题经过“非”运算后,结果为假。
到这里,大家可能会问,为什么对0进行“非“运算结果为-1,而对1进行“非“运算其结果为-2呢?
在经过上面一系列的操作后,大家应该知道,逻辑运算的操作也都是在数摞上进行的,操作前数摞上必须有参与逻辑运算的参数,操作后数摞上保留有逻辑运算的结果,在进行逻辑运算时,是按位进行运算的。如果数摞上的每一层都是一位的数,而不是32位的数,那么这时
1 非=0 0非=1
但是在汉语程序设计语言中数摞上的每一层数都是一个32位的数,所以在按位进行逻辑操作时,用1表示的逻辑真在数摞中只占用了一位,即:00000000000000000000000000000001,在进行“非”操作后,将32位的数“1”按位求反,结果就成为:11111111111111111111111111111110,这个数作为二进制补码的有符号数就显示为-2。
因此,在汉语编程中为了使逻辑运算更为适用,就规定对于一个32位的数,0为逻辑假,而非0为逻辑真。对于一个标准的汉语编程系统给出的逻辑真则为-1,这样我们最将前面程序中定义的逻辑真改为:
编 真 -1 。
这样在做上面的逻辑操作时,给出的逻辑真结果就是-1,而不是1。它保证了32位数中所有位都为1。
参考资料
最新修订时间:2023-12-10 14:42
目录
概述
数摞及运算方法
参考资料