大数的加减乘除、取对数、求次方、进制转换、三角函数的原理

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

说明:

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

2、第1点已经说了,这是针对整数的大数的运算,对于有小数的情况,请注意移位操作.例如3.5*4.5在大数里的运算是35*45,在最后的结果里移动2个小数点即可,而对于3.5/4.55则在大数里的运算应该是350/455,最后结果就不用处理小数点了.所以,如何处理小数点的问题,我想应该不难吧.如果处理小数点的问题,你都显得很困难,请你不用再看此文章了.

3、我们知道在VB.NET里,一个Long(Int64)类型的数据可以存储的最大整数是2^62=4611686018427387904,而2^31=2147483648即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为基来的)位数据.例如1234567894,我们用一个叫a的Long数组来存储的结果是a(0)=234567894,a(1)=1.需要注意的是,对应字符串"00002"这种数据的处理的时候,必须把前面的4个0处理掉而变成"2"再进行存储

一、大数加法

由说明里的第4点,写出源代码应该不难吧.就是同位数的对应想加,(下标一样的2个数组对应的数据是同位数的),这里注意加的时候是否存在进位的情况,也就是说加的结果如果大于(10^9-1)则存在进位.

看VB.NET源代码:大数加法

二、大数减法

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

看VB.NET源代码:大数减法

三、大数乘法

大数乘法原理很简单.用第一个大数的每9位数据(也就是一个数组元素)去分别乘另一个大数的每9位数据(也就是一个数组元素),然后把结果存储到对应的位数(数组元素)里去.这里注意进位的问题.

这里以一个例子来讲解其原理:300000000|000000004*600000000|000000007(这里用|主要是加以区分)则大数运算时,首先我们初始化一个返回值内存ret=0,先进行4*7=28,ret=ret+28=28,然后用4*600000000=2|400000000,注意这里,因为600000000是存储在数组的第二个元素,也就是说这个数据是被缩小了(2-1)*10^9,也就是说那准确的值是2|400000000|000000000,则ret=ret+2|400000000|000000000=2|400000000|000000028,下面就是300000000*7=2|100000000,由于300000000原来是在数组的第2个元素,其也是被缩小了(2-1)*10^9,也就是说其准确值应该是2|100000000|000000000,则其加上ret后得ret=4|500000000|000000028……

其实上面例子看起来很复杂,但是用数组操作是很快的,因为要对应位我们只对应下标就足够了.

看VB.NET源代码:大数乘法

四、大数除法与求余

1、除法

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

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

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值