问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

C++编程,如何处理大数的问题?2

发布网友 发布时间:2023-09-23 15:58

我来回答

3个回答

热心网友 时间:2024-10-20 03:40

这是代码,如果要用,要先自己调试一下才行。

struct Node // 定义一个双向链表用来存贮结果
{
char data; // 数据*定义为字符的原因:要显示负号
Node *next; // 尾指针
Node *ahead; // 首指针
};

/*--------------------------------------------------------------------------
*函数名称: 大数加法
*函数过程:1 比较两个数那一个长
* 2 以长的作为循环次数
* 3 对应项相加 进位存贮直到下高位相加用
* 4 直到循环结束
* 5 !!!!!!没设计负数相加
*入口参数:numa,numb,result字符串
*出口参数:无
*编辑环境:winSP2 + VC2003 + C++
*--------------------------------------------------------------------------*/
void addition(char *numa, char *numb,char *result) // 计算两大数之和
{
char *pna = findend(numa); // 指向numa的一个指针。point numa pna 指向乘数的最低位,
char *pnb = findend(numb); //指向numb的一个指针 //pnb 指向被乘数的最低位,
int along=(int)strlen(numa); //标记数字a的长度;
int blong=(int)strlen(numb); //标记数字b的长度;
int times = 0; // 标致要计算多少次。
int carry=0,temp_result; //存贮进位 和临时结果的
Node *head, // 用于存贮头指针
*pstart, // 用于存贮计算时的首指针
*pnew; //作于申请新结点
head = pstart =new Node; //初始化首结点和头结点。
pstart -> data = 0;
pstart -> next = NULL;
pstart -> ahead = NULL;

if (abigerb(numa ,numb)>=1)
times = (int)strlen(numa); //比较两个字符串长度,以大的作为循环次数
else
{
times = (int)strlen(numb);
pna = findend(numb); //交换指针
pnb = findend(numa);
along=(int)strlen(numb); //标记数字a的长度;
blong=(int)strlen(numa); //标记数字b的长度;
}
while ((times-- && (times>=0))|| carry != 0)
{
if(!pstart->next) //如果当前为空结点,则申请新结点
{
pnew = new Node;
pnew -> data = 0;
pnew -> next = NULL;
pnew -> ahead = pstart;
pstart -> next = pnew;
}
else temp_result =(pstart->data +(*pna-48)+(*pnb-48)+carry) ; //自身的值+新值+进位 作为当前的新值

pstart -> data = temp_result%10; //存贮个位
carry = temp_result/10; //存贮进位
pstart = pstart -> next; //结点移动
blong--;
if(blong>0)pnb--; //指针移向被加数高位
else *pnb=48; //之后相减就变为了0不作任何运算;
pna--; //加数指针移动,
}
pstart =head; //寻找链表的结尾点
while(pstart->next != 0)
{
pstart->data += 48; //!!<<<因为我们的输出是字符。所以再此加上48>>>> 逆顺输出
pstart = pstart->next ;
}

int tip = 0; //转为字符串用
pstart = pstart->ahead ; //找有效字
//cout<<"\n结果是 : ";
while(pstart != 0) //输出正序的结果;
{
result[tip++] = pstart->data;
//cout< data;
pstart = pstart->ahead ;
}
result[tip] = '\0';

pstart =head; //释放空间
while(pstart->next != 0)
{
pnew = pstart->next ;delete pstart;
pstart =pnew;
}
return ;
}

//比较两个数字符串大小的函数
//返回值说明:0是alongblong ; 2是along=blong
int abigerb(char *numa, char *numb) //比较两个数最高位那一个大
{
int along=(int)strlen(numa); //标记数字a的长度;
int blong=(int)strlen(numb); //标记数字b的长度;
char *pna = numa; //指向数A的最高位,
char *pnb = numb; //指向数B的最高位,
if (along>blong) return 1;
if (along==blong)
{
while(*pna) //比较两个数那一个大
{
if(*pna>*pnb)return 1;
else if(*pna<*pnb)return 0 ;
else if(*pna==*pnb) //1111与1112
}
return 2; //这表明找到最后了还是全相等;
}
return 0 ;
}

/*--------------------------------------------------------------------------
*函数名称: 大数减法
*函数过程:1 比较两个数那一个长
* 2 以长的作为循环次数
* 3 如果两个数长度相等,从最高位开始比直到发现那一个数更大,使大项减去小项
* 4 对应项相减 进位存贮直到下高位相加用
* 5 每一位对应项相减时,处理三种可能的情况,a=b,ab;
* 6 a=b时,则计算,11-12,111-112,要考虑借位
* 7 直到循环结束
*入口参数:numa,numb,result字符串
*出口参数:无
*--------------------------------------------------------------------------*/

void subtract(char *numa, char *numb,char *result)//计算减
{ char *pna = findend(numa);//指向numa的一个指针。point numa pna 指向减数的最低位,
char *pnb = findend(numb);//指向numb的一个指针 //pnb 指向被减数的最低位,
int along=(int)strlen(numa);//标记数字a的长度;
int blong=(int)strlen(numb);//标记数字b的长度;
int times = 0; // 标记要计算多少次。
int carry=0; //存贮借位
int clear0=0; //消除结果最前面无用的'0' 13-5 = 08 的效果!!
int isnegative=0; //用来加上被减数大于减数时补上最后一个负号
Node *head, // 用于存贮头指针
*pstart, // 用于存贮计算时的首指针
*pnew; //作于申请新结点
head = pstart =new Node;//初始化首结点和头结点。
pstart -> data = 0;
pstart -> next = NULL;
pstart -> ahead = NULL;
if (abigerb(numa ,numb))
times = strlen(numa);//比较两个字符串长度,以大的作为循环次数
else //交换位置以降低难度
{
times = strlen(numb);//让数(字符串)长的减去数(字符串)短的
pna = findend(numb);//交换指针
pnb = findend(numa);
along=(int)strlen(numb);//标记数字a的长度;
blong=(int)strlen(numa);//标记数字b的长度;
isnegative=1;//标记最后要加上负号
}
while ((times-- && (times>=0))|| carry != 0)//carry != 0 说没有借位时
{
if(!pstart->next)//如果当前为空结点,则申请新结点
{
pnew = new Node;
pnew -> data = 0;
pnew -> next = NULL;
pnew -> ahead = pstart;
pstart -> next = pnew;
}
if(times<0)//如果计算完之后,借位等于1,,说明必然为负值;
{ pstart -> data = -3 ;//让它等于负号 '-'//-3来源于负号与0相差3。。
break; }
else
{
if ( *pna == *pnb )//减数等于被减数时。结果等于直截相减的结果;并置借位为0
{
if(carry==0)pstart -> data = (*pna-48)-(*pnb-48); //111-11的情况
else
{
pstart->data = (*pna-48)-(*pnb-48)+10 -carry;//1121-1112 carry=1;
}
}
if( *pna > *pnb )//减数大于被减数时。结果等于直截相减的结果;并置借位为0
{
pstart -> data = (*pna-48)-(*pnb-48)-carry; //存贮个位
carry=0;
}
else if( *pna < *pnb )//说明被减数大于减数,让结果加10,相当于借位 (carry)为1
{ if(times>0)
pstart->data = (*pna-48)-(*pnb-48)+10 -carry;//13-5的情况作为新值
else
pstart->data = (*pnb-48)-(*pna-48) -carry; //3-5 作为当前的新值
carry=1;
}
}
pstart = pstart -> next;
//结点移动
blong--;
if(blong>0)pnb--;//指针移向被减数高位
else *pnb=48;//之后相减就变为了0不作任何运算,其实可以优化的。但代码会长!而且还需要重新开结点。所以放弃; pna--;//被数指针移动,
}
if(isnegative==1)////加上负号处理。增加一长度并置为负号
{
pnew = new Node;
pnew -> data = 0;
pnew -> next = NULL;
pnew -> ahead = pstart;
pstart -> next = pnew;
pstart->data=-3;//因为寻找链表的结尾点要统一加48。又因为‘-’是45。所以等于‘-3’
}
pstart =head;//寻找链表的结尾点
while(pstart->next != 0)
{
pstart->data += 48;//!!<<<因为我们的输出是字符。所以再此加上48>>>> 逆顺输出
pstart = pstart->next ;
}
int tip = 0;//转为字符串用
clear0=0;// 消除结果最前面无用的'0' 13-5 = 08 的效果 ..>>修改字符串的首指针
pstart = pstart->ahead ;//找有效字
while(pstart != 0)//输出正序的结果;
{ if(clear0==0 && ((int)pstart->data)==48&&pstart->ahead!=0)// 消除结果最前面无用的'0' ;
//不输出任何东西
else
result[tip++] = pstart->data;
if(((int)pstart->data)!=48&&((int)pstart->data)!=45)clear0=1;//'-'号
pstart = pstart->ahead ;
}
result[tip] = '\0';
pstart =head; //释放空间
while(pstart->next != 0)
{
pnew = pstart->next ;
delete pstart;
pstart =pnew;
}
return ;
}
/*--------------------------------------------------------------------------
*函数名称: 大数乘法
*函数过程:1 输入两个大数作为字符串
* 2 作一个双向链表
* 3 两个指针分别指向数字字符串的最低位
* 4 以第一个数的最低的一个位乘以第二个数的所有项存于链表中
* 5 链表首指针移
* 6 重复4,5依次从最低位乘到最高位
* 7 乘完后因为最低位是链表首,最后一位是链表尾。所以在逆顺输出链表。
* 4 直到循环结束
*入口参数:numa,numb,result字符串
*出口参数:无
*--------------------------------------------------------------------------*/

void multiply(char *numa, char *numb ,char *result)//用来储结果的)//计算乘积
{ char *pna = findend(numa);//指向numa的一个指针。point numa pna 指向乘数的最低位,
char *pnb = findend(numb);//指向numb的一个指针
//pnb 指向被乘数的最低位,
int along=(int)strlen(numa);//标记数字a的长度;
int blong=(int)strlen(numb);//标记数字b的长度;
int carry=0,temp_result;//存贮进位 和临时结果的
Node *head, // 用于存贮头指针
*pstart, // 用于存贮计算时的首指针
*pnew, //作于申请新结点
*pgo; //作为每计算完一行时,回到下一行起始节点用,移位标致来用
head = pstart =new Node;//初始化首结点和头结点。
pstart -> data = 0;
pstart -> next = NULL;
pstart -> ahead = NULL;
while (along--)
{
pgo = pstart;//保存进位点
blong = (int)strlen(numb);//初始化长度
pnb = findend(numb); //初始化指针
while ((blong-- && (blong>=0))|| carry != 0)
{ if(!pstart->next)//如果当前为空结点,则申请新结点
{ pnew = new Node;
pnew -> data = 0;
pnew -> next = NULL;
pnew -> ahead = pstart;
pstart -> next = pnew;
}
if(blong<0)temp_result = carry ;//处理只有进位的情况
else temp_result =(pstart->data+(*pna-48)*(*pnb-48)+carry);//自身值+新值+进位作为新值
pstart -> data = temp_result%10; //存贮个位
carry = temp_result/10; //存贮进位
pstart = pstart -> next; //结点移动
pnb--; //指针移向被乘数高位
}
pstart = pgo->next; //前进一个位置;
pna--; //指针移向乘数高位
}
pstart =head;//寻找链表的结尾点
while(pstart->next != 0) {
pstart->data += 48;//!!<<<因为我们的输出是字符。所以再此加上48>>>> 逆顺输出
pstart = pstart->next ; }
int tip = 0;//转为字符串用
pstart = pstart->ahead ;//找有效字
while(pstart != 0)//输出正序的结果;
{ result[tip++] = pstart->data;
pstart = pstart->ahead ; }
result[tip] = '\0';
pstart =head; //释放空间
while(pstart->next != 0) {
pnew = pstart->next ;
delete pstart;
pstart =pnew;
}
return ;
}

/*--------------------------------------------------------------------------
*函数名称: 大数除法2--
*函数想法:1 用指针指向除数的最高位,保存临时字符串; tempstr[a++] = pna
* 2 如果临时字符串大于被除数,则相减。结果等于余数
* if(tempstr>numb)tempstr = tempstr - numb
* 3 如果小于被除数且指针到头,余数 等于 临时字符串
* if(tempstr *
*入口参数:numa,numb,result,remainder字符串
*出口参数:无
*--------------------------------------------------------------------------*/

void divide2( char *numa, char *numb,char *result,char *remainder)//计算除法2
{ char one[]="1";//临时字符串....
char one2[]="1";//
char zero[]="0";//
char numb2[6048];//
char tempstr[6018]="";//临时字符串 i
nt ia=0,ia2=0;//tempstr的指示器
bool moveon=false;//翻转牌
char *pna = numa;//指向numa的一个指针point numa pna //指向减数的最低位,
char *pnb = findend(numb);//指向numb的一个指针 //pnb 指向被减数的最低位,
Node *head, // 用于存贮头指针
*pstart, // 用于存贮计算时的首指针
*pnew; //作于申请新结点
head = pstart =new Node;//初始化首结点和头结点。
pstart -> data = 0;
pstart -> next = NULL;
pstart -> ahead = NULL;
moveon = false; while(*pna)
{ if(!pstart->next)//如果当前为空结点,则申请新结点
{ pnew = new Node;
pnew -> data = 0;
pnew -> next = NULL;
pnew -> ahead = pstart;
pstart -> next = pnew; }
ia=(int)strlen(tempstr);//取的长度
tempstr[ia++] = *(pna++);
tempstr[ia] ='\0'; //转换为字符串
if(tempstr[0]=='0')//处理高位也是0的那种 如00
{
ia2=0;
while(tempstr[ia2]=='0')++ia2;
while(ia2>=1)//清除无用的0
{
ia=ia2-1;
tempstr[ia]=tempstr[ia2];
--ia2;
}
tempstr[++ia2]='\0';
}
while(abigerb(tempstr,numb)>0)//如果tempstr大于等于numb
{
if(tempstr[0]=='0')//处理高位也是0的那种 如00----此乃冗余代码,留做记念用
{
ia2=0;
while(tempstr[ia2]=='0')++ia2;
if(ia==ia2 )

}
strcpy(numb2,numb);
subtract(tempstr, numb,tempstr);//A-B strcpy(numb,numb2);
if(tempstr[0]=='-')//若判断的不准,变为了负数就再加上B。。
{
strcpy(numb2,numb);
addition(tempstr, numb,tempstr);//A-B
strcpy(numb,numb2);
ia2=0; //修正之后的长度。因为加法中未做负数运算
ia=0; //为了消除最后的那一个负号,整体向前移动。
while(tempstr[ia2]!='\0')++ia2;
while(ia2>=1)//清除无用的0 {
tempstr[ia]=tempstr[ia+1];
++ia;
--ia2; }
tempstr[ia]='\0';
moveon = true;
break; }
pstart->data++ ; //结果自加
moveon = true; }
if(moveon) pstart = pstart -> next; //结点移动
}
strcpy(remainder,tempstr);//存贮余数
int tip = 0;//转为字符串用
pstart =head;//寻找链表的结尾点
while(pstart->next != 0) {
pstart->data += 48;//!!<<<因为我们的输出是字符。所以再此加上48>>>> 逆顺输出
result[tip++] = pstart->data;
pstart = pstart->next ; }
result[tip] = '\0';//存贮结果
pstart =head; //释放空间
while(pstart->next != 0) {
pnew = pstart->next ;delete pstart; pstart =pnew; }
return ;
}
另外,虚机团上产品团购,超级便宜

热心网友 时间:2024-10-20 03:41

要处理大数,可以用整形数组(双链也行)或者字符串模拟

1) 如果需要处理大数乘法,最好自己设计一个能够处理无限大整数的Class,并且重载乘法操作符
2) 如果只需要做加减或者除法, 可以用字符串模拟, 2075可以用字符串做减法模拟.

热心网友 时间:2024-10-20 03:41

C++可以处理到64位的整形数,不知道你想处理多少位的呢?
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
华硕笔记本电脑触摸板怎么开笔记本电脑触摸板怎么开启和关闭_百度知 ... 陕西职务侵占案立案准则 结婚后我的恋情维系了十年,怎么做到的? 玉米仁子饭产自哪里 中国期货交易所的交易品种有哪些? 历史要怎么读,有啥诀窍 高中历史诀窍 年终会活动策划方案 深度解析:第一财经回放,探索财经新风向 逆水寒手游庄园怎么邀请好友同住 C++代码冗余,请问如何简化? 德语兔子怎么说???急!!! 什么花束适合送产后的妈妈 赵雅芝黑超遮面与老公十指紧扣秀恩爱是怎么回事?4 介绍你最喜欢的获奖科幻小说~~~15 你知道哪些著名的科幻小说?56 知道和QQ号能找到他的手机号 上古卷轴5白色斑点马位置 怎么通过,QQ号查找未 华为P10plus的拍照设置怎么办最清晰?2 华为p10plus怎么拍照清晰1 ...要如何有效的拉筋才能够劈腿? 还有,我的胸部是平的,要如何健身... 福特福克斯两厢2.0手自一体运动型发动机和性能怎么样? 梦幻西游端游怎么查找自己的角色? 为什么所有微信好友的都变成了wxid开头的一些数字? 电脑开机后一直显示AptioSetup是什么问题? 想退车怎么办?1 被盗了,如何找回? 冲动按揭买车后悔了,想退车。该怎么办?76 如何用剪映调整视频时长 电脑开机自动进入aptio怎么办? 肇庆什么地方有跌打馆! 如何查询自己名下的QQ号和(实名认证过的)?6 砂锅可以放在燃气灶上用吗 分手后让对方对你念念不忘的话 谁能帮我算下这个电源的额定功率是多少? 大哥帮我算下我电脑电源额定功率 华为p10plus相机怎么设置最佳32 上古卷轴5都是白色星星 中国科技最后可能在哪些方面弯道超车?1 谁能帮我算一下这个电源的额定功率? c# image 不支持url 格式 300字作文4226 刚刚今天买了车想退车了怎么办5 跪求小学生300字作文2 亚洲龙可变悬挂软硬调节什么意思 谁能帮我计算这电源额定功率和最大功率是多少 孕妇维生素b12偏低有什么危害 创造环境节作文300字5 看了你对2011款两厢福克斯2.0运动版的评价感觉挺好的,能帮我分析下2011...