C++大数操作Plus
来源:互联网 发布:php超链接 编辑:程序博客网 时间:2024/06/05 10:56
按照上次的思路,最近又重新实现了加减法以及大数的乘法,除法的话,实现起来难度还有点大,有比较好的思路再来续写吧。
#include<iostream>#include<cstdlib>#include<cstdio>#include<memory.h>#include<cstring>#include<cmath>#include<algorithm>#include<vector>#include<queue>#define mem(array) memset((array),0,sizeof((array)))#define Qsort(array,len,cmp) qsort(array,len,sizeof(array[0]),cmp)#define inf 0x7fffffff#define BigLen 10000 // length of the big number's array is BigLen#define BigCarry 1000 // carry of the big number's array is BigCarry/***Assumption bigNum is a big number,then the bigNum[0] is the lowest order digit while bigNum[BigLen-2] is the highest order digit and bigNum[BigLen-1] is sign bit.bigNum[BigLen-1] is -1 means bigNum is a negative number while bigNum[BigLen-1] is 1 means bigNum is a positive number or zero.We could define big number like this:int bigNum[BigLen];PS:I'm so sorry for my pool English. */using namespace std;bool add(int *sum, int *bigNum, int num);bool add(int *sum, int *bigNumA, int *bigNumB);int compare(int *bigNum,int num);int compare(int *bigNumA,int *bigNumB);int getTopPos(int *bigNum);bool input(int *bigNum, char *str);bool isBigNum(int *bigNum);bool multiply(int *product, int *bigNum, int num);bool multiply(int *product, int *bigNumA, int *bigNumB);bool output(int *bigNum);bool subtract(int *sub, int *bigNum, int num);bool subtract(int *sub, int *bigNumA, int *bigNumB);bool transBig2Num(int *bigNum, int &num);bool transNum2Big(int *bigNum, int num);bool isBigNum(int *bigNum){ /*** return true if the bigNum is legal big number while return false if not */ for(int i = 0; i < BigLen-1; ++i) if(bigNum[i] < 0 || bigNum[i] >= BigCarry) return false; if(bigNum[BigLen-1] != 1 && bigNum[BigLen-1] != -1) return false; return true;}bool input(int *bigNum, char *str){ /*** giving a integer string and a pointer of array which length equal to BigLen the integer string have to be made up of integer figure from 0 to 9 and character '-' which means negative number the function will return true if the string is legal while return false if not */ int len = strlen(str); if(len > (BigLen-1)*log10(BigCarry)) // the input string is too long so that the bigNum cannot save this number return false; int start = (str[0] == '-') ? 1 : 0; bool isdigit = true; for(int i = start; i < len; ++i){ if(str[i] < '0' || str[i] > '9'){ isdigit = false; break; } } if(!isdigit) return false; // the input string have some non numerical character except '-' int index = 0; int num = 0; int power = 1; for(int i = len-1; i >= start; --i){ num += (str[i]-'0') * power; power *= 10; if(power == BigCarry){ bigNum[index++] = num; num = 0; power = 1; } } if(num) bigNum[index++] = num; for(int i = index; i < BigLen-1; ++i) bigNum[i] = 0; bigNum[BigLen-1] = start ? -1 : 1; if(bigNum[0] == 0 && getTopPos(bigNum) == 0) // this will be work if input the string like "-00000" bigNum[BigLen-1] = 1; return true;}bool multiply(int *product, int *bigNumA, int *bigNumB){ /*** computing the product of both bigNumA and bigNumB */ if(product != bigNumA && product != bigNumB){ int topPosB = getTopPos(bigNumB); int productTemp[BigLen]; int carry; mem(product); product[BigLen-1] = 1; for(int i = 0; i <= topPosB; ++i){ int num = bigNumB[i]; carry = 0; mem(productTemp); productTemp[BigLen-1] = 1; for(int j = 0; j < BigLen-1; ++j){ carry += bigNumA[j] * num; productTemp[j] = carry % BigCarry; carry /= BigCarry; } if(carry) // return false if overflow return false; int topPosProductTemp = getTopPos(productTemp); if(topPosProductTemp + i >= BigLen-1) // overflow return false; for(int j = BigLen-2; j >= i; --j) productTemp[j] = productTemp[j-i]; for(int j = 0; j < i; ++j) productTemp[j] = 0; if(!add(product,product,productTemp)) return false; } delete productTemp; product[BigLen-1] = bigNumA[BigLen-1] * bigNumB[BigLen-1]; return true; } else{ int productTemp[BigLen]; mem(productTemp); if(!multiply(productTemp,bigNumA,bigNumB)) return false; for(int i = 0; i < BigLen; ++i) product[i] = productTemp[i]; delete productTemp; return true; }}bool multiply(int *product, int *bigNum, int num){ /*** computing the product of both bigNum and num */ int numSign; num = (num >= 0) ? (numSign = 1 , num) : (numSign = -1 , -num); if(num * BigCarry > inf){ int small[BigLen]; mem(small); transNum2Big(small,num); bool ans = multiply(product,bigNum,small); delete small; return ans; } else{ int carry = 0; for(int i = 0; i < BigLen-1; ++i){ carry += bigNum[i] * num; product[i] = carry % BigCarry; carry /= BigCarry; } product[BigLen-1] = bigNum[BigLen-1] * numSign; return carry ? false : true; // return false if overflow }}bool subtract(int *sub, int *bigNum, int num){ /*** computing the different of both bigNum and num */ // 这个好麻烦啊→_→ 不想写了,简单调用一下吧。。。(using English cannot express my feelings) // ignoring the above sentence, please int small[BigLen]; mem(small); transNum2Big(small,num); bool ans = subtract(sub,bigNum,small); delete small; return ans;}bool add(int *sum, int *bigNum, int num){ /*** computing the sum of both bigNum and num */ if(bigNum[BigLen-1] == 1){ if(num >= 0){ // bigNum >= 0 && num >= 0 int carry = num / BigCarry; int t = num % BigCarry + bigNum[0]; carry += t / BigCarry; sum[0] = t % BigCarry; for(int i = 1; i < BigLen-1; ++i){ t = carry + bigNum[i]; sum[i] = t % BigCarry; carry = t / BigCarry; } sum[BigLen-1] = bigNum[BigLen-1]; return carry ? false : true; // return false if overflow } else{ // bigNum >= 0 && num < 0 return subtract(sum,bigNum,-num); } } else{ if(num >= 0){ // bigNum < 0 && num >= 0 bigNum[BigLen-1] = 1; bool ans = subtract(sum,bigNum,num); if(bigNum != sum) bigNum[BigLen-1] = -1; sum[BigLen-1] *= -1; return ans; } else{ // bigNum < 0 && num < 0 bigNum[BigLen-1] = 1; bool ans = add(sum,bigNum,-num); bigNum[BigLen-1] = -1; sum[BigLen-1] = -1; return ans; } }}bool subtract(int *sub, int *bigNumA, int *bigNumB){ /*** computing the difference of both bigNumA and bigNumB */ if(bigNumA[BigLen-1] == 1){ if(bigNumB[BigLen-1] == 1){ // bigNumA >= 0 && bigNumB >= 0 if(compare(bigNumA,bigNumB) >= 0){ int carry = 0; for(int i = 0; i < BigLen-1; ++i){ carry += bigNumA[i] - bigNumB[i] + BigCarry; sub[i] = carry % BigCarry; carry = carry / BigCarry - 1; } sub[BigLen-1] = 1; return carry ? false : true; // return false if overflow } else{ bool ans = subtract(sub,bigNumB,bigNumA); sub[BigLen-1] = -1; return ans; } } else{ // bigNumA >=0 && bigNumB < 0 bigNumB[BigLen-1] = 1; bool ans = add(sub,bigNumA,bigNumB); if(bigNumB != sub) bigNumB[BigLen-1] = -1; return ans; } } else{ if(bigNumB[BigLen-1] == 1){ // bigNumA < 0 && bigNumB >=0 bigNumA[BigLen-1] = 1; bool ans = add(sub,bigNumA,bigNumB); bigNumA[BigLen-1] = -1; sub[BigLen-1] = -1; return ans; } else{ // bigNumA < 0 && bigNumB < 0 bigNumA[BigLen-1] = 1; bigNumB[BigLen-1] = 1; bool ans = subtract(sub,bigNumB,bigNumA); if(bigNumB != sub) bigNumB[BigLen-1] = -1; if(bigNumA != sub) bigNumA[BigLen-1] = -1; return ans; } }}bool add(int* sum, int *bigNumA, int *bigNumB){ /*** computing the sum of both bigNumA and bigNumB */ if(bigNumA[BigLen-1] == bigNumB[BigLen-1]){ // both bigNumA and bigNumB are negative or positive numbers int carry = 0; for(int i = 0; i < BigLen-1; ++i){ carry += bigNumA[i] + bigNumB[i]; sum[i] = carry % BigCarry; carry /= BigCarry; } sum[BigLen-1] = bigNumA[BigLen-1]; return carry ? false : true; // return false if overflow } else{ if(bigNumA[BigLen-1] == -1){ bigNumA[BigLen-1] = 1; bool ans = subtract(sum,bigNumB,bigNumA); if(bigNumA != sum) bigNumA[BigLen-1] = -1; return ans; } else{ bigNumB[BigLen-1] = 1; bool ans = subtract(sum,bigNumA,bigNumB); if(bigNumB != sum) bigNumB[BigLen-1] = -1; return ans; } }}bool transNum2Big(int *bigNum, int num){ /*** transferring a integer number to bigNum */ bigNum[BigLen-1] = (num >= 0 ? 1 : -1); num = (num >= 0 ? num : -num); int index = 0; while(num > 0){ bigNum[index++] = num % BigCarry; num /= BigCarry; } return true;}bool transBig2Num(int *bigNum, int &num){ /*** transferring a bigNum to a integer number */ int topPos = getTopPos(bigNum); if(int(topPos*log10(BigCarry) + log10(bigNum[topPos])) >= int(log10(inf))) return false; // return false if this num is not less than 1,000,000,000, but actually the biggest integer is 2,147,483,647(that is inf) num = bigNum[BigLen-1]; num = num*bigNum[topPos]; for(int i = topPos-1; i >= 0; --i) num = num*BigCarry + bigNum[i]; return true;}int compare(int *bigNum, int num){ /*** if bigNum > num, then return 1 if bigNum = num, then return 0 if bigNum < num, then return -1 */ int bigSign = bigNum[BigLen-1]; if(bigSign * num >= 0){ int topPos = getTopPos(bigNum); int bigDigits = topPos*log10(BigCarry) + log10(bigNum[topPos]); int numDigits = log10(num); if(bigDigits != numDigits) return bigDigits > numDigits ? bigSign : -bigSign; int big; if(transBig2Num(bigNum,big)){ if(big != num) return big > num ? 1 : -1; else return 0; } else{ int small[BigLen]; mem(small); transNum2Big(small,num); int ans = compare(bigNum,small); delete small; return ans; } } else{ return num > 0 ? -1 : 1; }}int compare(int *bigNumA,int *bigNumB){ /*** if bigNumA > bigNumB, then return 1 if bigNumA = bigNumB, then return 0 if bigNumA < bigNumB, then return -1 */ if(bigNumA[BigLen-1] != bigNumB[BigLen-1]) return bigNumA[BigLen-1] > bigNumB[BigLen-1] ? 1 : -1; // both bigNumA and bigNumB are positive numbers or negative numbers int sign = bigNumA[BigLen-1]; int topPosA = getTopPos(bigNumA); int topPosB = getTopPos(bigNumB); if(topPosA != topPosB) return topPosA > topPosB ? sign : -sign ; for(int i = topPosA; i >= 0; --i) if(bigNumA[i] != bigNumB[i]) return bigNumA[i] > bigNumB[i] ? sign : -sign ; return 0;}int getTopPos(int *bigNum){ /*** return the array index of bigNum's highest digits return 0 if the bigNum is zero */ for(int topPos = BigLen-2; topPos >= 0; --topPos) if(bigNum[topPos]) return topPos; return 0;}bool output(int *bigNum){ /*** output big number bigNum and carriage return is followed */ if(!isBigNum(bigNum)) return false; int topPos = getTopPos(bigNum); if(bigNum[BigLen-1] == -1 && (topPos || bigNum[topPos])) printf("-"); printf("%d",bigNum[topPos]); char formatLen[2] = {char(log10(BigCarry)) + '0'}; char format[6] = "%0"; strcat(format,formatLen); strcat(format,"d"); for(int i = topPos-1; i >= 0; --i) printf(format,bigNum[i]); printf("\n"); return true;}
欢迎各界大佬指出bug,非常感谢!
阅读全文
0 0
- C++大数操作Plus
- C的大数基本操作
- C Primer Plus-C语言字符串操作
- 大数乘法 - 大数作为字符串的C语言操作
- c plus plus 复习
- 《C primer plus》c语言位操作小函数
- Plus One 大数加1
- 大数操作
- 大数操作
- C primer plus第15章(位操作)
- c primer plus第15章总结:位操作
- C Primer Plus学习 二十一 指针操作
- C plus plus 的多态性
- c plus plus socket 编程
- c plus plus 第一章练习
- C Plus Plus Env Prepare
- C plus plus sprintf用法
- Leetcode#66. Plus One &&Add Binary (大数)
- 微信H5支付:网络环境未能通过安全验证,请稍后再试
- 小程序中页面跳转方法
- 2017云栖大会开源峰会预告
- OpenCV 中cv::Mat 和 IplImage 的转换与应用
- zabbix告警频率
- C++大数操作Plus
- STM32 基于串口RS485双机通信原理浅析
- Android画图Path的使用
- LATEX 入门模版
- Touch事件的产生及传递到DecorView的路线
- 创建夸库视图报错:SQL1101N SQLSTATE=08004
- 正则匹配函数
- JAVA面向对象编程艺术与思想:中文转拼音1
- 关于OpenCV中的多项式拟合polyfit函数的问题