大数类的简单实现

本文介绍如何在32位机器上使用VS2005进行大数操作,并实现了一个大数类用于处理超大数据。通过使用数组记录大数据,实现大数的转换、加减乘除等基本运算。

本文仅做参考,主要是体现大数实现原理。

 

大数操作是使用计算机计算经常遇到的问题。

使用VS2005,在32位的机器上

 

各个类型的大小:

sizeof(int): 4

sizeof(unsigned): 4

sizeof(long): 4

sizeof(long long): 8

sizeof(char): 1

 

因此,unsigned的二进制位数为:4*8=32位,能够表示的最大数为:4294967295

11111111 11111111 11111111 11111111

而 long long 最大能够表示的无符号数为2^64 -1=18446744073709551615

因此,实现一个大数类是很有必要的。

网上有很多以实现不错的大数类,我这里只是练习练习。

 

使用数组记录大数据:

 

 * 这里列举vector<char> dats表示大数

 *100000的二进制为:
 * 1111 01000010 01000000
 *将之存放到数组中为:
 * -----------------     -----------------        -----------------
 * |   第2个元素   |   |   第1个元素   |       |   第0个元素   |
 * -----------------     -----------------        -----------------
 * | | | | |1|1|1|1| | |1|0|0|0|0|1|0| | |1|0|0|0|0|0|0|
 * ----------------- ----------------- -----------------
 * 即:dats[0] = 64,dats[1] =66,dats[2]=15
 * 还原方法:((dats[2]*2^8)+dats[1])*2^8+dats[0] = 100000

 

 

定义一个大数类的结构:

class bigint 

{ 

    char sign;      //符号0:+, 1:-                   

    vector<unsigned> dats;

}

 

1.string转到dats,可以通过用2除来转为二进制。

例如:string numStr = 76543210;

首先由于末位为0,为偶数,所以记录0,结果为0

7&1==1 有补位给6, 7>>1 = 3

16&1==0 无补位, 16>>1 = 8

5&1 ==1 有补位给4 5>>1 = 2

14&1 ==0 无补位

 

最后得到38271605

由于末位为5,为奇数,所以再记录1,结果为10

在次除2得到19135802

由于末位为2,为偶数,所以再记录0,结果为010

.

最后当末位为1,为奇数,再记录1,结果为100100011111111010011101010

 

当然也可以采用分块计算,即把numStr分成多个整数,如:

numStr = 755432109876543210;

可以每次取8位放入到vector<unsigned> arr中,得到:

Arr = {75,54321098,76543210};

同样,也可以按照上面的除法,只是数组元素之间的补位值相当于10^8

如,第一个数75&1==1,所以补位为1,也就说,

下一个数是154321098>>1.

 

 

2.加操作:

对应dats各块,进行加,数组的每个位置和用long long carry记录,则该为的值 = carry & (1<<32 -1)

而进位值为carry>>32.具体需要注意位对齐细节,以及最后的进位处理,可能会进位多次。还要注意数的符号。

 

3.减操作:

减法是通过反码来实现的,其实就是利用越界来实现。

如:正数A 正数B,首先求正数B的反码

若当相减之后为正数,那就是(正数A + 正数B的反码)再加1.

若相减之后为负数,那么就是(正数A + 正数B的反码)再取反码。当然别忘了修改符号sign

 

对于乘除,则需要对数组各个部分进行分开来看,考虑进位即可。

跟加法很相似,只是原来各位置相加变为一个位置对应多个位置的相加。

 

4.除法操作:

按照位运算来操纵。

 

贴上代码,代码只是半成品,未经过测试,不能直接使用。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

丈八涯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值