求加减乘除四种运算统称什么运算的LISP

最近看了看lisp,有了点感想,如果你不知道什么是lisp,希望你先去百度百科一下,并看一下一篇叫做lisp的本质的文章。
果然我也开始不断的跟别人重复说,lisp到底有多好多好。。。
lisp是一门很接近人工智能的语言,也是最适合开发人工智能程序的语言。它的很多思想,能在大工程项目中得到实际应用。

简要来说,lisp是一门函数式编程语言,lisp的每个程序段都是极为灵活的,都能被保存起来,并进行修改,这种思想,我将其称为程序等价数据的思想。程序本身也是数据。

但如果你将函数定义成这样:

以下是大数运算的算法,没有经过科学论证,也没有参考算法书,只是自己想的,如果你有更快的算法,请也给我一份,让我参考一下.

1、以下说的大数运算均是针对是大自然数的运算,至于负数大数的运算,我想只要实现了正数大数的运算,负数的大数的运算应该不难吧.

2、第1点已经说了,这是针对整数的大数的运算,对于有小数的情况,请注意移位操作.例如里,一个Long(Int64)类型的数据可以存储的最大整数是2^62=7387904,而2^31=即10^10>2^31>10^9,为了进行大数的运算,我们得充分利用Long给我们的存储空间,我们这里选择10^9为基,为什么我们这里不是用10^10或者更大的数据为基呢,那是因为2个10^10以内的数据相乘,结果可能超过Long类型存储空间的2^62,而为什么不选择2^8或者更小的数据为基呢,因为我们这里得充分利用Long类型的存储空间,而10^9为基就正好适合我们的选择.之前在网上看到有很多人进行大数运算时是1位1位取出来进行运算的,那相当于是以10^1为基进行运算,那是相当慢的(用汇编移位操作的除外,这篇文章不涉及汇编的知识,不涉及C语言里的位的操作的知识).所以下面讲解的算法都是以10^9次方为一个基进行讲解的.注意10^9表示9位数据.

4、为了对大数进行快速运算,我们这里以Long类型的一维数组来存储大数,其存储原理是数组根据下标由小到大依次存储大数的低位到高位,数组里的元素每次存储大数9(由第3点的10^9为基来的)位数据.例如,我们用一个叫a的Long数组来存储的结果是a(0)=,a(1)=源代码:

在进行大数减法时,最好先判断大数的大小.首先是数组长度的判断,数组越长,这个数据肯定越大.如果数组长度一样,每对应的数组元素进行比较,直到被减数不小于减数,这样大数减法还必须返回一个判断返回值是否是负数的标志,我们这里返回的是其绝对值.当正负判断好之后,和大数加法一样,就是同位数的对应相减,(下标一样的2个数组对应的数据是同位数的),这里注意减的时候是否存在借位的情况.

(大数的除法应该在大数的基本运算中算是最困难的了.之前在网上看介绍,说的是大数的除法用大数的减法来实现,对于本文这种大数的算法格式,用大数减法来实现效率是相当慢的,因此我追求的是另一种方法)

首先我们这里考虑的大数除法是除数是不大于被除数的情况,如果除数大于被除数的除法,请先把被除数扩大N倍,然后再进行下面的运算,最后在结果里移动小数点即可.例如3/600,我们可以用,对结果向左移动4(3变成30000相当于3*10^4)个小数点就变成0.005

1、除数的位数不大于9时(代表大数的数组个数为1),被除数按高位依次对除数做除法,注意余数要加到下一次计算当中去.这个很简单

2、如果除数位数大于9位时(代表大数数组个数大于1),为了加快运算速度,把除数的位数扩大,扩大的其位数刚好为n*9位为止,扩大的同时注意被除数是否需要扩大,这个自己考虑即可,例如除数为,扩大后变成|源代码:

其实上面的除法已经可以求余了。但是对于a^b%c这种情形的求余,建议使用这种方法

六、大数取自然对数的算法,即我们如何快速算log(x)这类问题

其实这个问题很简单,先求大数以10为底取对数,然后在结果乘以Log(10)即得我们想要的结果.为什么是以10为底而不是其它值,因为以10为底只是移动小数点的问题,这个用计算机来实现很简单.这里需要理解的是log10(提供给我们的数学函数进行运算,即Math.Log(CDbl(A))即得我们的结果.

这个原理和(1)的原理差不多,(1)是把小数点移位数相加,这里是相减即可.例如Log(提供给我们的函数Math.Pow(10,n2*b)即可得到a^n2的值,最后把a^n2的值带回第2点即可得到我们想要的解.

4、需要说明一点的是,这种算法算然简单,速度快,但它是一种取近似的算法,即结果一般只能保证前面几位数的准确性

看下面的一个编程计算的结果

里很容易就可以用其提供的数学函数进行运算.然后把a^n2的值带回第2点即可得到我们想要的解.

2、16进制大数转10进制大数

和10进制转16进制一样,这个也得把16进制分成整数部分与小数部分.

(1)对于整数部分的转换.

把16进制从低位到高位每7位划分为一个区域,对每个区域转换成10进制(这个很容易就可以办到),然后从最低区域开始每个乘16^7,每上升一个区域均多乘一次16^7,这样最后把每个区域的值用大数加法加起来即得我们想要的结果.注意,当中如何尽量少的进行乘法的运算,这里不再多说.

(2)对于小数部分的转换.

在大数运算中,尽量避免除法运算是一种较好的选择.本方法就只需要进行一次除法即得我们想要的结果.假如我们的小数部分为B,这里注意,请把B变成位数为7n的数据.例如B=1234567FE那么变换后成为B=000,小数点后数据末尾添加0不影响数值大小.那么按照第(1)点对于整数部分的转换,假如把B转换成了一个大整数BB,那么我们这个时候小数部分的精确值=BB/(16^7)^n,现在再利用大数精确的除法来获得我们想要的结果是轻而易举的事情.

3、同样的道理,如果10进制与2、8、32进制进行转换时,先把2、8、32转换成16进制,然后再通过16进制与10进制的转换方法获得转换结果,最后再代入相应的结果里面即可.2、8、32进制与16进制的转换是不会丢失数据的转换关系,其转换方法非常简单,这里不再多说.


通过上面的我们已经可以对任意数据的,进行常规的加、减、乘、除、次方、取对数,那么求双曲函数已经不成问题,在我们常见的数学运算当中,就只剩下sin与cos函数了,其它的三角函数可以由他们推出来,即我们这里主要讨论大数级别的正弦函数与余弦函数的求解。

原理:《》、《》、《》

总结:上面的文字写得有点乱,但是总算把大数在初等数学领域内的计算问题解决.剩下的事情就是查找更好的算法了.在这里拭目以待吧!


Lua、ML、Haskell和Lisp这几种语言,哪个与面向过程的C++差别最大? [问题点数:63分,结帖人SukerZ]

面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。 面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。
前言: 如果你很想搞明白面向对象是什么,面向过程是什么,或者说二者之间的区别是什么,那么就花费一点时间来研读一下这篇博客,你一定会有很大的收获的! 一、面向对象与面向过程的区别 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了;面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个
scheme属于lisp的一种方言,语法规则
面向过程    优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发,性能是最重要的因素。    缺点:没有面向对象易维护、易复用、易扩展    面向对象    优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护 
目前无论是Lisp还是Javascript(C++就更不用说了),递归深度都远远低于可用内存大小,而且栈一旦分配就无法挪动(有指针似乎无解),这个问题的根源在于call指令会把下一指令的地址入栈。我经过几年的思考终于发现,可以把C++的内存模型完全放在堆上,也就是说进行call之前先new出调用函数所需要的空间,而把返回地址作为参数传递进去。这样就从根源上解决了此问题,那什么尾递归就是个渣,完全没
?? Java面向对象与c语言面向过程的不同 面向过程和面向对象的区别: 面向对象和面向过程,其实就是关注一件事情的角度不同,比如说:你想看AV(AmericanVideo) 面向过程是: 面向对象是: 从上面两张图不难看出,面向过程是一个自给自足的过程,它需要考虑第一步干什么,第二步干什么。。。 而面向对象是直接无视过程,不关

我要回帖

更多关于 加减乘除四种运算统称什么 的文章

 

随机推荐