超长整数的基础运算 算法实现之准备篇

首先解决问题1:如何表示如何表示一个超长整数?

为了模块化编程,程序结构清晰易懂。本文在开始之前先对大整数做一个结构封装,使用一个结构体来表示大整数。

标示符HBigInt表示一个多精度的大整数结构: 

typedef struct	/* 定义大整数的结构 */
{
     long int alloclen;	   /* 数组已经分配总的空间大小 */
   long int length;	   /* 大整数的长度,即系数的个数 */
     int sign;	      	   /* 大整数的符号 */
     un_short *pBigInt;    /* 大整数的数据 */
} HBigInt;
上面大整数封装的结构中,分别记录大整数分配到的空间alloclen大小和已经在使用到的空间length大小。

使用这种结构能够有效地管理内存,减少堆操作的次数,减少相关操作带来的性能损失;

通过一个指针来指向保存大整数的数据的数组,这样有利于内存的动态调整,

可以不移动数组的任何元素而交换两个大整数,其只需要交换三个内置的整数值和一个指针就可以了。

本文所讨论的大整数的数位是按照低位在前的方式存放,

则按从低位到高位的顺序把大整数的数位按下标从小到大顺序存放到数组中去,

也就是十进制表示方式相反方向,这样既有利于扩展大数的长度也有利于缩减。

因为在编程的时候很多的变量字符比较长,很容易略写某个字符,造成编程错误,

所以本文首先对一些变量进行预定义。

typedef unsigned int un_short;		/*16位数的声明符号*/	
typedef unsigned long un_long;         	/*32位数的声明符号*/
#define BIT_PRE_WORD	16UL		/* 每个单精度数字含有的bit数 */
/* 定义返回标识 */
<pre name="code" class="cpp">#define RETURN_OK_BINT		      0		/* 正常返回 */
<pre name="code" class="cpp">#define RETURN_FAILE_BINT             1         /*错误返回*/
<pre name="code" class="cpp"><pre name="code" class="cpp"><pre name="code" class="cpp">#define FAILE_MEMORY_BINT   	      2		/* 分配堆空间失败返回值 */
<pre name="code" class="cpp"><pre name="code" class="cpp"><pre name="code" class="cpp">#define INITIAL_BINT                  49        /* 默认分配的大小 */
<pre name="code" class="cpp"><pre name="code" class="cpp"><pre name="code" class="cpp">#define STEP_BIINT                    16        /* 起跳值 */ 

 
 
 
 
 
 
 
 
 
 
 对于大整数的符号,本文只区分正数与负数,若大整数的sign分量为1则表示该大整数是正数, 

这要求其它函数在运算到使sign分量为-1的保证设置该大整数为负。用un_short表示大整数的一位数字,

一下简称单字或字,两倍于un_short大小的则称为双字,三倍于un_short大小的则称为三字,

由于双字用un_long来表示,已经达到了32位CPU的字长。
因为在大整数的基本运算中,很多的操作都是类似和重复的,所以本文在开始介绍基本运算之前,先对这些基础函数进行说明。

函数initHBInt(HBigInt *hbi, long size = 49)的目的是初始化一个大整数,默认长度是49字节。

函数deleteHBInt(MBigInt *hbi)用于释放大整数所得的堆内存,并将符号标记为非负,要再次使用该数则必须先重新初始化;

在较复杂的函数中,若某一步(例如调用子函数)执行失败,则需要调用deleteHBInt函数释放该一步之前初始化的所有的大整数以免做成内存泄漏。

函数extendHBInt(HBigInt *hbi,long size)以STEP_BINT为增量在原来的大小上递加直到大于size,然后分配该大小的数位保存数据。

因为我们最为熟悉的数字和使用的最多的也是十进制表示形式,所以本文对大整数的输入和输出都是使用十进制形式。

函数readHBInt(HBigInt *hbi,char *str)是将十进制表示的字符串读入并转换为大整数结构表示;

函数writeHBInt(HBigInt *hbi,char *str)将大整数转换为十进制的字符串表示。当然可以通过对以上两个函数的修改,形成不同的B进制输入和输出方式。

函数Left_shift_word(HBigInt * dst,int n)用于将大整数dst左移n个字即乘以B^n;

函数Right_shift_word(HBigInt * dst,int n)则用于将dst右移n个字,这相当于除以B^n。

函数Left_shift_bit(HBigInt *dst, HBigInt *src)用于将大整数src左移1个bit即乘以2,将结果保存到dst中;

函数Right_shift_bit(HBigInt *dst, HBigInt *src)则用于将src右移1个bit即除以2,将结果保存至dst中。计算结果取下整。

同理以下是加、减、乘、除的函数定义:

addHBInt(HBigInt* dst, HBigInt* src1, HBigInt* src2);
subHBInt(HBigInt* dst, HBigInt* src1, HBigInt* src2);
mulHBInt(HBigInt* dst, HBigInt* src1, HBigInt* src2);
divHBInt(HBigInt *a, HBigInt *b, HBigInt *c, HBigInt *d);

至于每个形参的意义会在下一篇中讲解函数实现的时候介绍。


未完,待续。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值