婚姻的四则运算

2024-06-23

婚姻的四则运算(精选3篇)

婚姻的四则运算 第1篇

在科学研究和工程计算里面经常会遇到超长整数的计算问题。所谓超长整数是指整数的数值非常大,位数非常多,以至于超出了计算机程序设计语言所能表示的整数范围。超长整数的四则运算是指至少有一个超长整数作为操作数的四则运算。为了能够精确地得到超长整数四则运算的结果,需要设计专门的数据结构来存储超长整数,以及配套的算法来实现这些运算。目前对于超长整数的四则运算有很多研究[1,2,3,4,5,6,7,8,9,10,11],但这些研究给出的算法都有不尽完善之处。有的是四则运算没有全部给出[1,2,3,4,5,6],有的是四则运算的存储结构不统一[6,7],有的是运算后破坏了操作数的值[8,9],有的是算法复杂,将原本可以合并讨论的若干种可能性分解开来[10,11]。本研究以C/C++作为程序设计语言,以字符数组为作为存储结构,探讨了一套相对完善的无符号超长整数的四则运算实现算法。

1 算法的设计目标

通常使用的存储结构有数组[1,2,3,6,7,9,10,11]和链表[4,5,6,7]这2种。存储结构本身并无明显的优劣之分,链表和数组都有其优缺点。采用链表能适应超长整数的位数变化,不需要预先知道超长整数的位数,但是链表的操作会导致额外的系统开销;采用数组方便直接存取数据,但需要预先知道超长整数的最大位数,预先定义数组长度会导致存储空间的浪费。四则运算的算法设计要围绕事先选定的存储结构来展开。本研究认为一套相对完善的超长整数四则运算的算法应满足如下的设计目标。

(1)运算的完备性。四则运算包括加减乘除4个基本运算和较为复杂的混合运算,其中混合运算可以按照运算的优先顺序拆分成若干个基本运算的组合。许多研究给出的算法是不完备的,有些没有给出相对复杂的除法运算[1,2,3,4,5,6],有些虽然给出了除法运算却忽略了简单的加减法运算[10],这使得算法的可参考性大打折扣。因此,一套具有运算完备性的超长整数四则运算算法至少要考虑同时给出4种基本运算。

(2)存储结构的统一性。使用链表还是数组作为存储结构不是问题,关键在于4种基本算法使用的存储结构要统一,否则,如果同一套算法需要准备多个存储结构[6,7],会使得算法的实用性大大降低。

(3)操作数的非破坏性。非破坏性是指参与运算的两个操作数在运算之后仍能保持原来的值不变。在连续的很多次运算中,很可能要用到同一个操作数,如果该操作数的值在每一次参与运算之后都破坏,那么整个算法的可重用性就不会太好。文献[6]和文献[9]给出的算法在运算中破坏了操作数。好的算法应该能保证操作数可以一次赋值、多次使用。

(4)算法逻辑的简单性。算法在逻辑上应该尽量简单,最好不要将原本可以合并讨论的若干种可能性分解开来。文献[9]将超长整数的乘法运算和除法运算各自分为若干情况来讨论,文献[10]将除法运算分为若干种可能的情况讨论,这种做法增加了算法的复杂性。其实乘法运算和除法运算虽然复杂,但完全可以用统一的算法进行处理。

(5)算法使用的方便性。这里的方便性有两层含义。一是过程简单;二是结果全面。

过程简单是说让程序员调用这些算法模块需要的准备工作越少越好。例如,采用链表当存储结构的时候,算法应该自行解决超长整数的常规形式到链表形式的转换,而不应该让程序员先进行转换然后再进行运算。还有设计减法算法的时候,大部分研究都认为小数减去大数的问题可以转化为大数减去小数的问题,从而只给出了大数减去小数的算法,对算法使用者来说这是不太方便的,因为这需要程序员学会在特定存储结构的约束下进行大小数比较,这限制了算法的使用。

结果全面是说算法应该尽量为用户提供全面的操作结果。如果用户需要得到超长整数相除运算的商带小若干位数,算法没有这个功能就是不方便。目前所有的算法都是只提供整数商,有的还提供余数,但没有任何一个算法提供带小数的商。

2 用字符数组存储超长整数

2.1 选用字符数组的原因

当前的计算机硬件配置一般都会很高,存储空间的浪费不再是主要的问题,大家更关心运算的速度,因此本研究采用数组作为存储结构。采用数组作为超长整数的存储结构,又有2种不同的选择:整数数组和字符数组。从理论上讲,字符和数字互相转换多了一个步骤,所以整数数组会优于字符数组,但本研究选定的是字符数组。原因如下:

(1)在C/C++语言中,字符类型和整数类型在一定范围内是通用的,而且一个数字字符的ASCII值和它对应的数字整数差了一个48,即字符'0'的ASCII。所以,这种转换不需刻意进行,可以在运算的时候即时完成。因此,在运算方面,字符数组同整数数组一样方便。

(2)在数据的输入输出和其他一些操作(例如逆转操作数、比较操作数大小)方面,采用字符数组就可以使用现成的C/C++函数,这比采用整数数组方便。

(3)采用整数数组而且逆序存放操作数的话,从运算算法上来看是最简单的,文献[11]就是采取的这个做法,其给出的加、减、乘算法简捷有效,但是算法没能明确给出运算结果的数据位数,为数据输出和下一步的运算造成困难。用字符数组则避免了这个问题,既不用额外设定变量保存数据位数,又能很方便地确定数据的位数,使用字符串长度函数即可。

2.2 用字符数组表示超长整数

科学研究和工程计算中用到的超长整数以正数居多,除非在减法运算的时候才能遇到结果的符号问题,如果将减法运算的数值结果和正负符号分成2部分来表示,那么所有的超长整数都将是无符号的。这里说的超长整数都是指无符号超长整数。而且,长度很短的无符号整数,哪怕只有1位,将也被视为超长整数对待。

用字符数组表示超长整数需要事先定义字符数组的长度,即确定超长整数的最大可能位数。可以把这个数定的大一些,可以保证字符数组在存储和运算的时候不会越界,这样即使浪费点内存空间也是可以接受的。基于此,在以后的讨论中不考虑字符数组越界问题。

超长整数在字符数组中以字符串的方式存放。字符串的构成方式是按照操作数从高位到低位的顺序排列的,其中的每个数字字符对应超长整数的一位数字整数。设有超长整数A=1234567890存储在字符数组a[]当中,则a[]当中各个字符的分布如下(C/C++的数组下标从0开始):

在超长整数存储的时候还要注意一点,有些数字可能有前导0,例如字符串“00123”和“123”表示的是同一个数123。算法当中要对“00123”这种不规范的表示方法进行规范化处理,变成“123”这样的规范化形式。对于多个连续字符‘0’构成的字符串,规范化之后的字符串要保留一个‘0’字符。

3 超长整数四则运算算法

3.1 加法

3.1.1 思路

加法操作的算法跟手工做加法运算的过程完全一致,从两个操作数的最低位(在字符数组中对应最后一个有效字符)开始逐位相加,一直加到最高位(对应字符数组的第一个字符)为止。加的过程中将结果逐位写入目标数组的对应位置,并设置相应的进位标志,进位标志的初始值为0。由于进位的存在,不知道最终结果的位数是否多于2个操作数的最大位数,所以将操作结果在目标数组中选择逆序存放的,即先存结果数据的低位。加法结束后,如果进位标志不为0,则在结果的最后补上1个字符‘1’。最后将操作结果对应的字符数组倒置,使操作数变为顺序存放。注意相加的时候让两个数字字符各减去48,即字符‘0’的ASCII值,最后得到的操作结果的每一位都要加上48之后再存入结果数组。倒置数组可以使用C/C++语言的strrev()函数。下面给出C/C++源代码形式的算法(为了节省篇幅,算法中略去了源代码中对参数合法性判断的部分和对数据规范化处理的部分,下同)。

3.1.2 程序

程序如下:

3.2 减法

3.2.1 思路

两个操作数都存入字符数组,由于减法运算涉及到运算结果的符号问题,所以将运算结果的数值部分和符号部分分别存放。数值部分以字符串的形式存入字符数组;符号部分存入一个整型变量,其值为1的时候,结果是非负的,其值为-1的时候,结果为负。

这里采取一个与众不同的思路做减法运算:将减法变成加法。开始首先比较两个操作数的大小,比较的时候使用字符串求长度函数和字符串比较函数相结合,原则是(规范化之后的数字)字符串较长的操作数大,如果长度相等,则两操作数的大小取决于字符串比较函数strcmp()的返回值。

接下来将较小的操作数对应的字符串高位补0使得它的位数跟较大的操作数位数一样多。然后将补位之后的较小操作数每一位都按9取反(被9减),末位加1,这个步骤类似二进制的负数取补码操作。

然后调用加法运算的算法将两个操作数相加。如果结果字符串长度如果比较大操作数的位数还大,就把字符串最左边的字符‘1’删去,然后去掉结果字符串最左边可能有的字符‘0’。得到的字符串就是操作结果的数值部分。

举例如下:62-109。

因为62<109,所以符号部分的值为一1,下面看数值部分的求解步骤:

(1) 62补足3位:062;

(2)按位对9取反,末位加1:938;

(3) 109和938进行加法运算:1047;

(4)结果4位,大于3,将最高位的1去掉:047;

(5)最高位的0去掉:47。

由此可以得到减法运算的结果:-47。

上述思路只是为了将事情说清楚而设定了几个步骤,实际上在操作过程中可以将(2)、(3)两步合起来进行简化:假定较大的操作数为A=anan-1…a1,较小的操作数为B=bmbm-1…b1,那么,结果R的任意一位可以用如下的公式表示:

式中:1≤i≤n,carry的初值为1。这里当i>m时,bi取0值。这个算法源于化简为加的思想,但仔细比较一下这个算法跟文献[11]给出的借位算法(x是大数,n位数字,y是小数,m位数字):

式中:1≤i≤n,borrow的初值为0。

会发现2个算法殊途而同归,有异曲同工之妙。后者方便理解,但前者从算法形式上看更为简单。

3.2.2 程序

程序如下:

3.3 乘法

3.3.1 思路

乘法运算的算法一般是仿真手工做乘法的思路来设计。从乘数的最低位开始,按由低位到高位的顺序依次取出一个数字,用它去乘被乘数的每一位,所得到的数据累加到结果的相应位置上,在每两位数字相乘并累加之后马上着手进位操作[1,3,8,9,11]。实际上这种精确仿真会增加算法的操作次数,因为进位操作是在二重循环中进行的。比较理想的办法是粗略仿真,在累加完每两位数字的乘积之后不马上进行进位操作,而在乘法和累加操作全部进行完之后,再统一处理进位问题。以999×88为例,算法过程如图1所示。

从逻辑上看,这种粗略仿真方法较精确仿真方法效率更高,因为累加运算的执行次数同精确仿真一样多,但进位运算的次数却少很多。如果采用短整型(short int类型)数组的话,在每个数组元素存储一位数字的情况下,可最多执行2个404位的超长整数进行乘法运算而不发生溢出。但使用字符数组作为超长整数的存储结构时,却不能采用这种高效的方法。因为字符数组每个单元占8个二进制位,所能存储的整数是有限度的,当累加的结果超过一定数值的时候会造成数据溢出,从而使乘法的结果不再准确。

解决的办法有2种:一是采取动态申请内存缓冲区的做法,乘法前申请一个足够大的整型数组,采用粗略仿真方法得到乘法结果之后,再将乘积存储到字符数组中,最后再释放相应的内存空间,这种做法需要申请和释放内存空间,需要额外的系统开销。二是仍然按照精确仿真的办法去做,通过即时进位来消除数据溢出现象,这种做法需要忍受复杂度为O(mn)的进位操作。要想综合比较两种方法的优劣可能是比较困难的,就本文的研究所面临的应用来看,申请和释放内存空间的系统开销非常大,反倒是理论上效率不高的精确仿真的算法更能节省时间。

本研究采用建立在字符数组基础上的精确模拟算法。首先是设定结果缓冲区,以字符‘�’填充。然后按照即时进位的办法做乘法运算,结果缓冲区当中按照由低位到高位的顺序存储乘积结果的每一位。乘法结束后,找到结果缓冲区的结束位置,并将该缓冲区的结果字符串逆转,便得到最终的乘积结果。

3.3.2 程序

程序如下:

3.4 除法

3.4.1 思路

本算法考虑设计一个多功能的除法器,除了能返回整数商和余数之外,还能按照设定的小数位数返回带指定小数的商,如果将小数位数设定为0,返回的商就是整数商。

首先在被除数开头截取一定长度的字符串,使得该字符串对应的数字刚好大于除数(如果被除数小于除数,则截取整个字符串),截取的这段字符串作为临时被除数的初值。此后不断地用临时被除数除以除数,得到的商存入结果缓冲区相应位置,余数作为新的临时被除数,并从被除数当中每次截取一个字符加入到新的临时被除数的后面,再去除以除数,得到新的商和余数。执行一次除法运算的时候采用若干次减法运算来代替,做减法的次数就是当前一次除法的商。当被除数当中的字符截取完毕的时候,此时的临时被除数就是余数,如果小数位数大于0,则在商的末尾添加小数点标记,此后不断地往临时被除数后面补充字符‘0’,继续除以除数,并将当前商放到商缓冲区的末尾。当最后不再补充‘0’的时候,除法结束。

3.4.2 程序

程序如下:

4 算法分析

假定第一个操作数和第二个操作数的位数分别为m和n(m,n≥1),令max取值为m和n当中的较大者。则加法运算和减法运算的时间复杂度都是O(max),乘法运算的时间复杂度为O(mn)。除法运算因为考虑到小数位数,稍微复杂一点,时间复杂度为O((m-n+nXiaoshuCount)n),当m

这套算法符合前文提出的5个设计目标。4个算法齐备,符合完备性要求。4个算法都是基于字符数组设计,符合存储结构的统一性要求。4个算法都没有破坏操作数,符合操作数的非破坏性要求。乘法和除法都是统一的算法,没有根据操作数的情况分成多种可能的情况进行讨论,符合算法逻辑的简单性要求。减法运算能处理小数减大数的情况,除法运算同时提供商和余数,还能提供带小数的商,这都是过程简单和结果全面的具体体现,符合算法使用的方便性要求。

另外,本文以程序代码的方式给出算法模块,具有很高的实用性。在补齐检验参数有效性和进行数据规范化的预处理代码之后,4个程序模块能够很方便地集成到应用程序当中。

5 应用

文献[12]给出了依存结构树的概念和计数公式,并给出了结点数在8以内的依存结构树的数目。但是随着结点数目的增大,依存结构树的数目以指数规律增长,到依存结构树的结点大于等于15的时候,C/C++语言中的long数据类型已经容纳不下它的计数结果。采用本文给出的超长整数的四则运算算法和代码,得到了精确的计数结果。尤其是其中的带小数功能的除法算法,为寻找计数结果的增长规律提供了技术保证。

6 结语

本研究给出的在综合比较现有研究成果的基础上,设计了一套相对完善的无符号超长整数四则运算算法。研究中提出的化减为加的思想和据此给出的减法算法为同类研究所未曾提及,首次给出了乘法运算的精确模拟和粗略模拟之间时间复杂性比较,给出的带小数功能的超长整数除法算法也是此前的研究所欠缺的。

摘要:通过对现有超长整数四则运算的算法的综合比较,提出一套相对完善的算法的设计目标。基于字符数组提出一套无符号超长整数四则运算算法,给出了加减乘除4个算法的逻辑思路和程序代码,精确实现了超长整数的四则运算,并将算法应用于科学研究的实践当中。

关键词:超长整数,四则运算,字符数组,算法

参考文献

[1]刘国玉.借助数组完成长整数的精确运算[J].中文信息, 2003(11):105-106.

[2]黄师化,汪光运.利用数组和字符串实现长整数的精确计算[J].安庆师范学院学报:自然科学版,2007(3):107-109.

[3]杨翠萍,成润梅.采用数组研究实现长整数的精确计算方法[J].现代电子技术,2008,31(14):151-152.

[4]岳国英.长整数加减运算的精确实现[J].河北工程技术高等专科学校学报,1999(2):14-18.

[5]岳国英.长整数乘法运算的精确实现[J].河北工程技术高等专科学校学报,1999(3):16-21.

[6]乌兰图雅.C语言中实现超长整数加法运算的方法[J].阴山学刊:自然科学版,2005(1):11-13.

[7]杜丽娟,鞠宏军.用C语言实现超长整数的加减乘除四则运算[J].电脑开发与应用,2003(5):36-38.

[8]龚成清.基于delphi的超长整数四则运算的实现[J].宁波职业技术学院学报,2005(5):27-30.

[9]龚成清.超长整数运算的精确实现[J].福建电脑,2005 (10):144-145.

[10]孔丽英.超长整数的表示与计算[J].肇庆学院学报,2002 (5):59-62.

[11]任治斌,王存良,耿国华,等.超长整数四则运算实现方法的研究[J].通信技术,2007(6):57-59.

带括号的四则运算教学反思 第2篇

1、将理解运算顺序与解决问题相结合

教学中充分运用了学生感兴趣的生活情境,放手让学生独立思考,自主体验,并在合作交流的基础上形成解决问题的步骤和方法,每一步算什么?求的是什么问题?将解题的步骤与运算的顺序有机地结合起来。在正确与错误算式的对比中,引导学生发现如果不带小括号就出现了“下午游人数减去上午保洁员数”的错误结果,认识到了引入小括号的必要性,感受括号的实用价值。在具体的情境中通过对比由学生自己归纳出带小括号的四则运算的运算顺序,印象更加深刻。

2、注重培养学生掌握解决问题的步骤和策略。

解决问题的步骤和策略也是教学的重点和难点之一。第二种解题方法学生理解起来比较困难。首先,引导学生认真解读题意,重点解读“如果每30位游人需要一名保洁员”,为学生分析数量关系,寻求解题思路作好铺垫。其次,让学生交流解题思路,并借助线段图帮助学生进行理解,实际效果比较好。第三,重视两种不同解决方法的对比,使学生体会到解决问题的思路不同,解决方法也不同,计算的步数也不一样,实现对解题方法的优化,切实培养了学生解决问题的能力。

3、从不同的角度进行对比、分析,强化小括号的作用。

在例5的教学中引导学生从有无括号、括号的位置、括号的多少等不同角度引导学生进行分析和比较,让学生自己说说“有什么感受”,进一步加深了学生对括号的认识。同时也培养了学生认真书写的习惯。不足:

1、还存在操之过急的现象。学生在用第二种方法解决问题的时候。有的学生出现了没用小括号计算。这个时候应该让学生结合题来说一说,可以不可以,为什么。那么在课堂中是由我来告诉学生的。

2、对于学情分析还不够透彻。在例5的教学中,我认为学生对这样的问题经过前面的学习应该不存在障碍。可以是实际解决的过程中,学生的问题比较多,体现在不参与计算的数怎么办,运算顺序不清晰等等。那么在教学过程中,虽然针对学生出现的情况进行了及时的讲解,但也一直在反思学生出现这种无从下手的情况的原因是什么。感觉还是学生对于前面学习的知识掌握得不够扎实,另外我认为在教学中也应该培养学生的综合运用知识的能力。

我的思考:

1、认真细致研读教材。在备课的过程中要充分地备教材,理解教材的编排意图,不走弯路。在备课的过程中把教材的编排意图,课标的要求以及自己的理解和班级学生的实际情况相统一。

2、学生倡导“活动式”教学,那么在这类计算教学中,我们也要提倡活动,学生的思维要参与到活动中来,积极动脑思考。那么在教学过程中,我们就要给学生创设这样的机会。

婚姻的四则运算 第3篇

A.面对婚姻的保鲜,我们要善于用加法

在婚姻的城堡里夫妻朝夕相对,时间久了难免会产生“审美疲劳”。我们要学会做加法,为婚姻“保鲜”。今天,你展示一下自己刚学的厨艺,与爱人在烛光下甜蜜地共进晚餐;明天,在朋友的聚会上大秀火辣的探戈,引来交口称赞;后天,去美容院做个新发型,让爱人觉得耳目一新……一点点改变,就是一点点新鲜。让我们做一个常变常新的人,保持积极开朗的心态,不断充实自己,这不仅是为婚姻补充了新鲜感,也会让自己越活越精彩。

B.面对婚姻的负担,我们要善于用减法

婚姻就像一辆车,承载着整个家庭的希望。但是,如果超载运行,则婚姻不堪重负,往往事与愿违。其实,婚姻的幸福跟物质没有太多直接的联系。我们要学会辩证地看待婚姻,用减法减去婚姻里过重的负担。如果对生活要求过多,反而会让自己越来越累,不如简单一点、轻松一点,放弃生活中已成为你负担的东西,终止你无法承受的压力,减去一些可有可无的奢求,婚姻生活就会充满明媚的阳光。

C.面对婚姻的幸福,我们要善于用乘法

婚姻生活是相对独立的两人世界,但也不能仅仅是孤独的两人世界。在幸福的家庭里,我们孝敬父母,钟爱伴侣,抚育儿女,与亲人们共享其乐融融的天伦之乐,把每一个幸福的数字相乘起来,就一定会构成一个幸福的世界。

D.面对婚姻的烦恼,我们要善于用除法

在携手同行的道路上,要想时时事事都一帆风顺、一路平安是不可能的,总会遇上风风雨雨、坎坎坷坷。但只要两个人相依相伴、相守相携,患难与共,平分忧伤,就会共同走过风雨,走过四季,走过这人生的漫漫长路,始终不离不弃、相濡以沫、携手并肩去笑看人生的朝露夕阳,谁能说这不是一种幸福呢?

上一篇:技术推动模式下一篇:北斗通信论文