也来实现长整数得四则运算
2009-09-14 22:49
218 查看
即使我们有了64位的计算机,按内置方法我们一样处理不了大于20位的超长整数得运算,所以各种各样得办法被实现出来,闲来无事,我也弄了一块。
我选择string来保存结果,没有使用流行得串行结构,其本上就是想保留一个返回值,不过这个改起来也还是容易得,有心得朋友可以自己实现。其实目前得实现还只考虑了正确性,效率没多想,尤其是模运算,简直低效得吓人,有好得建议朋友们千万不吝赐教啊。
贴上来还有个目的就是希望朋友们能帮忙找些虫子,让我得代码能更加坚固,谢谢大家!
头文件
实现部分
我选择string来保存结果,没有使用流行得串行结构,其本上就是想保留一个返回值,不过这个改起来也还是容易得,有心得朋友可以自己实现。其实目前得实现还只考虑了正确性,效率没多想,尤其是模运算,简直低效得吓人,有好得建议朋友们千万不吝赐教啊。
贴上来还有个目的就是希望朋友们能帮忙找些虫子,让我得代码能更加坚固,谢谢大家!
头文件
#ifndef CBIGINT_H_ #define CBIGINT_H_ #include <assert.h> #include <iostream> #include <cstdlib> #include <cstdio> #include <string> #define MAX_NUM_LEN 10240 //结果最大长度 #define MAX_FLAX_LEN 30 //浮点数最大精度 class CBigInt { public: CBigInt(); ~CBigInt(); public: int add(const char* _first,const char* _second,std::string& _result); //加 int sub(const char* _first,const char* _second,std::string& _result); //减 int mul(const char* _first,const char* _second,std::string& _result); //乘 int div(const char* _first,const char* _second,std::string& _result); //除 int mod(const char* _first,const char* _second,std::string& _result); //模 int abscmp(const char* _first,const char* _second); int absncmp(const char* _first,const char* _second,int n); int set_max_f(int _len); private: int get_sigh(const char* _first,const char* _second); int check(const char* _num); int pure_add(const char* _first,const char* _second,std::string& _result); int pure_sub(const char* _first,const char* _second,std::string& _result); int pure_div(const char* _first,const char* _second,std::string& _result); int pure_mod(const char* _first,const char* _second,std::string& _result); int get_pure(const char* _first,const char* _second); int mul_single(const char* _first,const char _second,std::string& _result); private: int m_max_len; }; #endif
实现部分
#include "CBigInt.h" CBigInt::CBigInt():m_max_len(MAX_FLAX_LEN) { } CBigInt::~CBigInt() { } int CBigInt::add(const char* _first,const char* _second,std::string& _result) { assert(_first!=NULL && _second!=NULL); //检测操作数是否合法,并获取操作数的符号 int t_sigh = this->get_sigh(_first,_second); if (t_sigh == -1) { return -1; } //预定义负号 std::string csigh = "-"; switch(t_sigh) { case 0://如果是二个正数相加 this->pure_add(_first,_second,_result); break; case 1://如果第一个操作数为负 if(this->sub(_second,_first+1,_result) == 1) { if (*_result.c_str()!='0') { _result = csigh + _result; } } break; case 2://如果第二个操作数为负 if(this->sub(_first,_second+1,_result) == 1) { if (*_result.c_str()!='0') { _result = csigh + _result; } } break; case 3://如果二个操作数都为负 this->pure_add(_first+1,_second+1,_result); if (*_result.c_str()!='0') { _result = csigh + _result; } break; default: break; } if ((*(_result.c_str()+1) == '-'&&_result.length()==1) || _result.length()==0) { _result = "0"; } return 0; } int CBigInt::sub(const char* _first,const char* _second,std::string& _result) { assert(_first!=NULL && _second!=NULL); //检测操作数是否合法,并获取操作数的符号 int t_sigh = this->get_sigh(_first,_second); if (t_sigh == -1) { return -1; } //预定义负号 std::string csigh = "-"; int rel = 0; switch(t_sigh) { case 0://如果是二个正数相减,并且被减数大于减数 rel = this->get_pure(_first,_second); switch(rel) { case 0: _result = "0"; return 0; case 1: this->pure_sub(_first,_second,_result); break; case 2: this->pure_sub(_second,_first,_result); if (*_result.c_str()!='0') { _result = csigh + _result; } break; default: break; } break; case 1://如果第一个操作数为负 this->pure_add(_first+1,_second,_result); if (*_result.c_str()!='0') { _result = csigh + _result; } break; case 2://如果第二个操作数为负 this->pure_add(_first,_second+1,_result); break; break; case 3://如果二个操作数都为负 rel = this->get_pure(_second+1,_first+1); switch(rel) { case 0: _result = "0"; return 0; case 1: this->pure_sub(_second+1,_first+1,_result); break; case 2: this->pure_sub(_first+1,_second+1,_result); if (*_result.c_str()!='0') { _result = csigh + _result; } break; default: break; } break; default: break; } if ((*(_result.c_str()+1) == '-'&&_result.length()==1) || _result.length()==0) { _result = "0"; } return 0; } int CBigInt::mul(const char* _first,const char* _second,std::string& _result) { assert(_first!=NULL && _second!=NULL); //检测操作数是否合法,并获取操作数的符号 int t_sigh = this->get_sigh(_first,_second); if (t_sigh == -1) { return -1; } int flen = strlen(_first); int t_len = strlen(_second); char* s_result = new char[flen+t_len+2]; std::string t_result = ""; int i = 0,j=0,k=0; t_len--; while (t_len>=0) { this->mul_single(_first,_second[t_len],t_result); k = strlen(t_result.c_str()); memset(s_result,0,flen+t_len+2); strncpy(s_result,t_result.c_str(),k); while (j!=0) { s_result[j--+k-1]='0'; } i++,j=i,t_len--; this->add(_result.c_str(),s_result,_result); } //预定义负号 std::string csigh = "-"; switch(t_sigh) { case 1://如果第一个操作数为负 if (*_result.c_str()!='0') { _result = csigh + _result; } break; case 2://如果第二个操作数为负 if (*_result.c_str()!='0') { _result = csigh + _result; } break; default: break; } delete [] s_result; if ((*(_result.c_str()+1) == '-'&&_result.length()==1) || _result.length()==0) { _result = "0"; } return 0; } int CBigInt::div(const char* _first,const char* _second,std::string& _result) { assert(_first!=NULL && _second!=NULL); //检测操作数是否合法,并获取操作数的符号 int t_sigh = this->get_sigh(_first,_second); if (t_sigh == -1) { return -1; } //预定义负号 std::string csigh = "-"; switch(t_sigh) { case 0: this->pure_div(_first,_second,_result); break; case 1://如果第一个操作数为负 this->pure_div(_first+1,_second,_result); if (*_result.c_str()!='0') { _result = csigh + _result; } break; case 2://如果第二个操作数为负 this->pure_div(_first,_second+1,_result); if (*_result.c_str()!='0') { _result = csigh + _result; } break; case 3://如果第二个操作数为负 this->pure_div(_first+1,_second+1,_result); break; default: break; } if ((*(_result.c_str()+1) == '-'&&_result.length()==1) || _result.length()==0) { _result = "0"; } return 0; } int CBigInt::mod(const char* _first,const char* _second,std::string& _result) { assert(_first!=NULL && _second!=NULL); //检测操作数是否合法,并获取操作数的符号 int t_sigh = this->get_sigh(_first,_second); if (t_sigh == -1) { return -1; } //预定义负号 std::string csigh = "-"; switch(t_sigh) { case 0: this->pure_mod(_first,_second,_result); break; case 1://如果第一个操作数为负 this->pure_mod(_first+1,_second,_result); if (*_result.c_str()!='0') { _result = csigh + _result; } break; case 2://如果第二个操作数为负 this->pure_mod(_first,_second+1,_result); if (*_result.c_str()!='0') { _result = csigh + _result; } break; case 3://如果第二个操作数为负 this->pure_mod(_first+1,_second+1,_result); break; default: break; } if ((*(_result.c_str()+1) == '-'&&_result.length()==1) || _result.length()==0) { _result = "0"; } return 0; } int CBigInt::pure_add(const char* _first,const char* _second,std::string& _result) { int flen = strlen(_first); int slen = strlen(_second); int temp = 0; int t_len = flen>slen ? flen : slen; //动态分配存储结果数组,因为是加法,所以结果最大长度为最长操作数长度加1 //另加上一个结束符号位 char* t_result = new char[t_len+2]; if (t_result==NULL) { return -1; } memset(t_result,0,t_len+2); flen--,slen--; while (t_len >= 0) { if (flen<0) {//如果其中以个操作数已经循环完,则结果仅加上另一个操作数 t_result[t_len] += _second[slen]+48; } else if (slen<0) { t_result[t_len] += _first[flen]+48; } else { t_result[t_len] += _first[flen] + _second[slen]; } if (slen<0&&flen<0) { t_result[t_len] = 96; } //加上进位 t_result[t_len] += temp; temp = 0; if (t_result[t_len]>=106) {//如果结果达到进位,置进位标志,并将结果复位 t_result[t_len] -= 10; temp = 1; } //填写最终结果 t_result[t_len] -= 48; t_len--,slen--,flen--; } char* p = t_result; while (*p++=='0') { } _result = --p; delete []t_result; return 0; } int CBigInt::pure_sub(const char* _first,const char* _second,std::string& _result) { int flen = strlen(_first); int slen = strlen(_second); int temp = 0; int t_len = flen>slen ? flen : slen; //动态分配存储结果数组,因为是减法,所以结果最大长度为最长操作数长度 //另加上一个结束符号位 char* t_result = new char[t_len+1]; if (t_result==NULL) { return -1; } memset(t_result,0,t_len+1); flen--,slen--,t_len--; while (t_len >= 0) { if (slen<0) {//如果减数循环完 t_result[t_len] = _first[flen]-48; } else { t_result[t_len] = _first[flen] - _second[slen]; } //加上进位 t_result[t_len] -= temp; temp = 0; if (t_result[t_len]<0) {//如果结果达到进位,置进位标志,并将结果复位 t_result[t_len] = 10 + t_result[t_len]; temp = 1; } //填写最终结果 t_result[t_len] += 48; t_len--,slen--,flen--; } char* p = t_result; while (*p++=='0') { } _result = --p; delete []t_result; return 0; } int CBigInt::pure_div(const char* _first,const char* _second,std::string& _result) { int flen = strlen(_first); int slen = strlen(_second); char s_buf[3] = {0}; int t_pos = 0; int s_pos = 0; std::string t_first = _first; std::string t_result = ""; while (this->abscmp(t_first.c_str(),_second)==-1) { t_first += "0"; t_pos++; } int t_flen = 0; char flag = 0; int i,j = 1; bool t_flag = false; while (1) { i = 1; if (t_pos + j > MAX_FLAX_LEN+1) { break; } while (this->abscmp(t_first.c_str(),_second)==-1) { t_first += "0"; if(this->abscmp(t_first.c_str(),_second)==-1&&flag) { _result += "0"; j++; } if (!flag&&!t_pos) { _result += "."; if(this->abscmp(t_first.c_str(),_second)==-1) { _result += "0"; j++; } flag = 1; } } t_flen = t_first.length(); while (1) { t_result = ""; this->mul(_second,itoa(i++,s_buf,10),t_result); int rel = this->abscmp(t_result.c_str(),t_first.c_str()); if( rel == -1) { t_result = ""; continue; } else if (rel == 0) { t_flag = true; break; } else { t_result=""; this->mul(_second,itoa(i-2,s_buf,10),t_result); int t_len = t_result.length(); while (t_len+1<t_flen) { t_result+="0"; t_len++; } while (t_len>t_flen) { t_first+="0"; t_len--; } this->sub(t_first.c_str(),t_result.c_str(),t_first); break; } } _result += s_buf[0]; if (t_flag) { break; } j++; } if (t_pos!=0) { t_result = "0."; while (--t_pos>0) { t_result += "0"; } _result = t_result + _result; } return 0; } int CBigInt::pure_mod(const char* _first,const char* _second,std::string& _result) { std::string t_result = ""; std::string s_result = "1"; int i = 0; while (1) { t_result = ""; this->mul(_second,s_result.c_str(),t_result); int rel = this->abscmp(t_result.c_str(),_first); i++; if( rel == -1) { t_result = ""; this->add(s_result.c_str(),"1",s_result); continue; } else if (rel == 0) { _result = "0"; break; } else { t_result = ""; this->sub(s_result.c_str(),"1",s_result); this->mul(_second,s_result.c_str(),t_result); this->sub(_first,t_result.c_str(),_result); break; } } return 0; } int CBigInt::mul_single(const char* _first,const char _second,std::string& _result) { _result = ""; int t_len = strlen(_first); char* s_result = new char[t_len+2]; memset(s_result,0,t_len+2); int i = 0,j=0; while (t_len-->=0) { s_result[0] = ((_first[t_len] - 48) * (_second - 48)/10)+48; s_result[1] = ((_first[t_len] - 48) * (_second - 48)%10)+48; while (j!=0) { s_result[j--+1]='0'; } i++,j=i; this->add(_result.c_str(),s_result,_result); } delete [] s_result; return 0; } int CBigInt::get_pure(const char* _first,const char* _second) { int flen = strlen(_first); int slen = strlen(_second); if (flen>slen) { return 1; } else if (flen<slen) { return 2; } else { int i = 0; while (i<flen) { if (_first[i]>_second[i]) { return 1; } else if (_first[i]<_second[i]) { return 2; } i++; } } return 0; } int CBigInt::get_sigh(const char* _first,const char* _second) { int t_sigh = 0; int func_rel = check(_first); if (func_rel == -1) { return -1; } else if (func_rel==1) { t_sigh += 1; } func_rel = check(_second); if (func_rel == -1) { return -1; } else if (func_rel==1) { t_sigh += 2; } return t_sigh; } int CBigInt::check(const char* _num) { char t_flag = 0; if (*_num=='-') {//剔除符号 _num+=1; t_flag = 1; } size_t len = strlen(_num); //该字符串过大,检测失败 if (len>MAX_NUM_LEN) { return -1; } int i = 0; while (*_num!=0) {//如果字符串中有不是数字的字符或没有结束符 if(*_num>'9'||*_num++<'0'||i++>=len) { return -1; } } return t_flag ? 1 : 0; } int CBigInt::abscmp(const char* _first,const char* _second) { if (*_first == '-') { return this->abscmp(_first+1,_second); } if (*_second == '-') { return this->abscmp(_first,_second+1); } int flen = strlen(_first); int slen = strlen(_second); if (flen>slen) { return 1; } else if (flen<slen) { return -1; } else { int i = 0; while (i<flen) { if (_first[i]>_second[i]) { return 1; } else if (_first[i]<_second[i]) { return -1; } i++; } } return 0; } int CBigInt::absncmp(const char* _first,const char* _second,int _n) { if (*_first == '-') { return this->absncmp(_first+1,_second,_n); } if (*_second == '-') { return this->absncmp(_first,_second+1,_n); } int flen = strlen(_first); int slen = strlen(_second); char* t_first = new char[flen+1]; char* t_secend = new char[slen+1]; memset(t_first,0,flen+1); memset(t_secend,0,slen+1); strncpy(t_first,_first,_n); strncpy(t_secend,_second,_n); int rel = this->abscmp(t_first,t_secend); delete [] t_first; delete [] t_secend; return rel; } int CBigInt::set_max_f(int _len) { m_max_len = _len; return 0; }
相关文章推荐
- java实现超大整数加减乘除四则运算
- C++实现高精度大整数(大数)的四则运算
- C#实现的简单整数四则运算计算器功能示例
- 用位运算来实现整数的四则运算
- C/C++ 实现整数四则运算
- 只用位运算来实现整数的加减乘除四则运算
- 输入一个整数数组,实现一个函数来调整该数组中数字的顺序使得 所有奇数位于数组的前半部分,所有偶数位于数组后半部分
- C语言,用数组实现结果为100000位内的大整数幂运算。
- java大整数四则运算
- 位操作实现加减乘除四则运算
- 整数转字符串的一种快速实现
- 用位运算实现两个整数的加减乘除运算
- 【剑指offer】C语言:实现函数可以将一个字符串转换为对应的整数,如+1234输出1234
- 逆波兰式实现四则运算表达式计算器支持括号、十六进制
- 栈实现四则运算
- 请实现一个队列,既可以存放整数,又可以存放字符串。简单的说,队列是一种数据结构,按照先进先出的顺序管理进、出队列的元素
- 数字0到9999转换大写汉字整数程序(C语言实现)
- 整数转换成罗马数字java实现
- 位运算之美——用+,-和位运算实现正整数除法和取模(一)