C++高精度计算一(练习题)

📅 2026/6/16 15:40:20
C++高精度计算一(练习题)
条件判断加法【描述】输入两个高精度大数字正整数将两个大数字相加若两数相等输出Equal否则输出它们的和。【输入描述】输入两个高精度大数字【输出描述】输出两个数字之间相加结果如果数字相等则输出“Equal”【样例输入1】123456789987654321【样例输出1】1111111110【样例输入2】111111111111111111111111111111【样例输出2】Equal#includeiostream#includecstringusingnamespacestd;// 定义最大数字长度常量预留1位符号位和1位终止符constintMAX1005;chara[MAX],b[MAX],res[MAX];// 输入字符串和结果数组// 比较两个数字字符串是否相等// 返回值true-相等false-不等boolisEqual(){if(strlen(a)!strlen(b))returnfalse;// 长度不同直接不等returnstrcmp(a,b)0;// 逐字符比较内容}// 条件加法函数相等则输出Equal否则计算两数之和voidconditionalAdd(){cinab;// 输入两个数字字符串// 判断是否相等if(isEqual()){coutEqual\n;// 相等时输出提示return;}// 获取字符串长度intlenAstrlen(a),lenBstrlen(b);// 反转存储数字到整型数组方便从低位开始计算intnumA[MAX]{0},numB[MAX]{0};for(inti0;ilenA;i)numA[i]a[lenA-1-i]-0;// 字符转数字并反转存储for(inti0;ilenB;i)numB[i]b[lenB-1-i]-0;intcarry0;// 进位标志// 逐位相加处理到最长长度for(inti0;imax(lenA,lenB);i){intsumnumA[i]numB[i]carry;// 当前位总和res[i]sum%100;// 当前位结果取模得数字转字符carrysum/10;// 计算进位}// 处理最高位进位if(carry)res[max(lenA,lenB)]carry0;res[max(lenA,lenB)1]\0;// 字符串终止符for(intistrlen(res);istrlen(res);i--)//反转顺序输出正确计算结果coutres[i];}intmain(){conditionalAdd();// 执行条件加法操作return0;}/* 【输入用例2】 123450000897 67845 【输出用例2】 123450068742 【输入用例3】 0000000000000000000 0000000000000000000 【输出用例3】 Equal 【输入用例4】 9999999999999999999 1 【输出用例4】 10000000000000000000 【输入用例5】 314159267895461462479415133648971892123649511 465489789461321564567897545613215645678948944 【输出用例5】 779649057356783027047312679262187537802598455 【输入用例6】 202020212022202320242025 199919981997199619951994 【输出用例6】 401940194019401940194019 */大数字减法【描述】输入两个高精度正整大数字可能被减数减数计算他们的差值结果可能是正数、0或负数。【输入描述】两个高精度正整大数字【输出描述】两者的差值【样例输入】10000000000000000001【样例输出】999999999999999999#includeiostream#includecstringusingnamespacestd;constintMAX10005;chara[MAX],b[MAX];intres[MAX]{0};// 逆序存储结果数值类型// 比较两个大数的数值大小长度优先再逐位比较boolisSmaller(constchar*a,constchar*b){if(strlen(a)strlen(b))returntrue;if(strlen(a)strlen(b))returnfalse;returnstrcmp(a,b)0;// 长度相同则逐位比较}voidsignedSubtract(){boolnegativefalse;// 正确判断数值大小关系if(isSmaller(a,b)){swap(a,b);negativetrue;}intlenAstrlen(a),lenBstrlen(b);intnumA[MAX]{0},numB[MAX]{0};// 逆序存储个位在前for(inti0;ilenA;i)numA[i]a[lenA-1-i]-0;for(inti0;ilenB;i)numB[i]b[lenB-1-i]-0;intborrow0;for(inti0;ilenA;i){intdiffnumA[i]-(ilenB?numB[i]:0)-borrow;if(diff0){diff10;borrow1;}else{borrow0;}res[i]diff;// 存储当前位结果}// 动态确定结果长度并去除高位零intresLenlenA;while(resLen1res[resLen-1]0)resLen--;// 输出结果带符号和逆序处理if(negative)cout-;for(intiresLen-1;i0;i--)coutres[i];// 逆序输出coutendl;}intmain(){cinab;signedSubtract();return0;}/* 【输入用例2】 123 45 【输出用例2】 78 【输入用例3】 123456489798456161321564 1 【输出用例3】 123456489798456161321563 【输入用例4】 000123 00045 【输出用例4】 78 【输入用例5】 123456789123 123456789123 【输出用例5】 0 【输入用例6】 123456789123456 123456789123789 【输出用例6】 -333 */计算高精度乘法ab【描述】a是一个很大的非负整数但不超过240位b是一个非负整数不超过10000求ab。【输入】两个非负整数每行一个【输出】两个数相乘的结果【输入样例1】11111111111111111111111111111111111110【输出样例1】1111111111111111111111111111111111110#includeiostream#includecstring#defineN250usingnamespacestd;inta[N];//用于存储拆解后的数字 ,全局变量默认初始化为0的数组intb;// 单精度数voidinit(){charac[N];cinac;a[0]strlen(ac);//a高精度数的位数存在a[0]中for(inti1;ia[0];i)a[i]ac[a[0]-i]-0;//将数字字符串ac转换成数组a,倒序存储数字}voidmul(){// 从低位到高位逐位相乘for(inti1;ia[0];i){a[i]a[i]*b;}// 处理进位for(inti1;ia[0];i){a[i1]a[i]/10;a[i]%10;}// 有新的进位长度1if(a[a[0]1]!0)a[0];// 去掉前导零while(a[a[0]]0)a[0]--;}intmain(){init();cinb;mul();if(a[0]0){// 乘积为0时长度因为去前导0变成0cout0;}else{for(intia[0];i1;i--)couta[i];}return0;}/* 【输入用例2】 125 25 【输出用例2】 3125 【输入用例3】 100 1000 【输出用例3】 100000 【输入用例4】 202520242023 1999 【输出用例4】 404837963803977 【输入用例5】 3141592679563214569871235644 2001 【输出用例5】 6286326951805992354312342523644 【输入用例6】 999999999999999999999999999999 0 【输出用例6】 0 */大数平方【描述】输入一个大数字正整数计算这个大数的平方【输入描述】输入一个正整数【输出描述】输出这个数的平方值【样例输入】31415926927【样例输出】986960464682603663329#includeiostream#includecstringusingnamespacestd;constintMAX4010;// 扩大数组容量2倍安全余量chara[MAX];intres[MAX]{0};// 初始化为0voidsafeSquare(){intlenAstrlen(a);intnumA[MAX]{0};// 逆序存储并去除输入前导零intstart0;while(startlenAa[start]0)start;lenA-start;for(inti0;ilenA;i)numA[i]a[startlenA-1-i]-0;// 双重循环计算平方带完整进位处理for(inti0;ilenA;i){for(intj0;jlenA;j){intproductnumA[i]*numA[j]res[ij];// 合并已有值res[ij]product%10;// 当前位res[ij1]product/10;// 进位}}// 动态确定结果长度处理最高位进位intlen2*lenA;while(len1res[len-1]0)len--;// 输出结果for(intilen-1;i0;i--)coutres[i];}intmain(){cina;safeSquare();return0;}/* 【输入用例2】 000000000000000000000000001 【输出用例2】 1 【输入用例3】 222222222222222222222222222 【输出用例3】 49382716049382716049382715950617283950617283950617284 【输入用例4】 1010101010101010101 【输出用例4】 1020304050607080910090807060504030201 【输入用例5】 2025 【输出用例5】 4100625 【输入用例6】 19999990000099999 【输出用例6】 399999600004099958000029999800001 */大数模运算【描述】计算两个大数之间的模运算结果如果模的值范围小于等于0或者大于1e9则输出“Invalid modulus”如果输入的数字中包含其他字符字母等则输出报错“Invalid input”。【输入描述】输入两个正整数模数与被模数【输出描述】输出模运算后的值【样例输入】1234456789 10000【样例输出】6789#includeiostream#includecstringusingnamespacestd;constintMAX1005;charnum[MAX];intmod;voidsafeMod(){// 输入验证if(mod0||mod1e9){coutInvalid modulusendl;return;}boolisNegativefalse;if(num[0]-){isNegativetrue;}intstart0;if(isNegative)start1;// 跳过负号intlenstrlen(num)-start;longlongres0;// 使用长整型防止中间溢出for(intistart;istrlen(num);i){if(num[i]0||num[i]9){coutInvalid inputendl;return;}res(res*10(num[i]-0))%mod;}if(isNegative)resmod-res;// 处理负数结果coutresendl;}intmain(){cinnummod;safeMod();return0;}/* 【输入用例2】 1234 1000 【输出用例2】 234 【输入用例3】 00099 3 【输出用例3】 0 【输入用例4】 1233156498789456156 12315645611 【输出用例4】 Invalid modulus 【输入用例5】 12a3 5 【输出用例5】 Invalid input 【输入用例6】 9999999999999999 1 【输出用例6】 0 */