昨天突然想写个计算器,支持无限位数结果的。于是乎就写了个...现在把写的过程记录下来,供大家互相学习!

首先,要做计算,我首先想到的就是逆波兰

百度查到的定义是

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

一个 表达式E的后缀形式可以如下定义:
(1)如果E是一个变量或 常量,则E的 后缀式是E本身。
(2)如果E是E1 op E2形式的表达式,这里op是如何二元操作符,则E的后缀式为E1'E2' op,这里E1'和E2'分别为E1和E2的后缀式。
(3)如果E是(E1)形式的表达式,则E1的后缀式就是E的后缀式。
如:我们平时写a+b,这是中缀表达式,写成 后缀表达式就是:ab+
(a+b)*c-(a+b)/e的后缀表达式为:
(a+b)*c-(a+b)/e
→((a+b)*c)((a+b)/e)-
→((a+b)c*)((a+b)e/)-
→(ab+c*)(ab+e/)-
→ab+c*ab+e/-

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

我的理解是:

把表达式看作符号和数字组成的字符串

如果是数字,就放到一个容器里,如果是符号则放到另一个容器里,然后根据逆波兰的规则,把符号容器里的符号依次提到存数字字符串的容器中,这样就能转换

比如:

(a+b)*c-(a+b)/e

1 存数字的容器:

1 存运算符的容器:(

2 存数字的容器:a

2 存

运算符

的容器:(

3 存数字的容器:a

3 存运算符的容器:(+

4 存数字的容器:ab

4 存

运算符

的容器:(+

5 存数字的容器:ab+
5 存运算符的容器:
6 存数字的容器:ab+
6 存 运算符的容器:*
7 存数字的容器:ab+c
7 存 运算符的容器:*
8 存数字的容器:ab+c*
8 存运算符的容器:-
9 存数字的容器:ab+c*
9 存运算符的容器:-(
10 存数字的容器:ab+c*a
10 存运算符的容器:-(
11 存数字的容器:ab+c*a
11 存运算符的容器:-(+
12 存数字的容器:ab+c*ab
12 存运算符的容器:-(+
13 存数字的容器:ab+c*ab+
13 存运算符的容器:-
14 存数字的容器:ab+c*ab+
14 存运算符的容器:-/
15 存数字的容器:ab+c*ab+e
15 存运算符的容器:-/
16 存数字的容器:ab+c*ab+e/
16 存运算符的容器:-
17 存数字的容器:ab+c*ab+e/-
17 存运算符的容器:
要注意以下几点:
1.要放入存运算符的容器前 先判断下优先级 如果要放入的运算符比前面的符号优先级低,则先将前面的运算符取出放到存数字的容器中 再放入运算符。
2.遇到右括号 则直接把前面到左括号之前的运算符都依次取出放入存数字的容器,左括号直接丢弃
3.如果后面已经没有字符了,而存运算符的容器里面还有字符,则依次取出放入存数字的容器
4.如果有连续两个- 则将前面一个-改为+ 
5.如果左括号前面没有 + - * / ( ^! 等运算符 则 在前面补个*
6.如果-是在第一个字符或者 - 前面是( 则这个-代表负数 可以用'#'来代表
//-----------------------------------------------------------------------------------------------------------------------------------------------------
当成功转成逆波兰算式以后,要计算起来就比较简单了。 我先写了个 直接转成double型的来做下实验。
在遇到字符的时候,如果是+-*/^其中之一 则取出前面两个数 a b, 进行 a 操作符 b 求出结果,然后把a b 取出 把结果存入,如果是!则只取前面一个数进行!a得出结果,把a取出,把结果存入,这样 最后就会得出一个结果,这个就是我们要求出的值了!
代码如下:
<pre name="code" class="cpp">
#include<iostream>
#include<vector>
#include<string>
#include<cstdio>using namespace std;#define LIFE '('
#define RIGHT ')'
#define THEPOW '^'
#define JIECHENG '!'
#define MUL '*'
#define DIV '/'
#define ADD '+'
#define SUB '-'class calculator
{
private:string import; //输入string outport; //输出vector<string> res_import; //转换后的输入public:calculator();~calculator();//输入 bool PutIn();//将输入的公式转换成逆波兰形式存储到vectorbool Change();//得到结果void GetResult();//输出void PutOut();//计算string DoCalculator(const string &a, const string &b, const char &fuhao);//优先级判断 是否低于前面bool IsLow(const char &a, const char &b);//优先级计算int FirstCode(const char &a);};calculator::calculator() :import(""), outport(""), res_import(NULL)
{}
calculator::~calculator()
{}
bool calculator::PutIn()
{import = "";getline(cin, import);if (import == "")return false;elsereturn true;
}
bool calculator::Change()
{vector<string> temp; //用来临时存储操作符号的string temp_str = ""; //用来临时存储数字for (int i = 0; i < import.size(); i++){string temp_fh = "";//数字if ((import[i] >= '0' && import[i] <= '9') || import[i] == '.'){temp_str.push_back(import[i]);}else if (import[i] == LIFE){if (i > 0 && import[i - 1] != LIFE && import[i - 1] != THEPOW && import[i - 1] && JIECHENG && import[i - 1] != MUL && import[i - 1] != DIV && import[i - 1] != ADD && import[i - 1] != SUB){if (temp_str != ""){res_import.push_back(temp_str);temp_str = "";}temp.push_back("*");}temp_fh = import[i];temp.push_back(temp_fh);}else if (import[i] == RIGHT){//把整个数字压入if (temp_str != ""){res_import.push_back(temp_str);temp_str = "";}//弹出括号里面的符号if (temp.size() > 0){string fuhao = temp.at(temp.size() - 1);while (fuhao[0] != LIFE){temp.pop_back();res_import.push_back(fuhao);if (temp.size() <= 0)break;fuhao = temp.at(temp.size() - 1);}//弹出左括号temp.pop_back();}}else if (import[i] == THEPOW || import[i] == JIECHENG || import[i] == MUL || import[i] == DIV || import[i] == ADD || import[i] == SUB){//把整个数字压入if (temp_str != ""){res_import.push_back(temp_str);temp_str = "";}//判断优先级 如果比前面的低 则弹出前面一个if (temp.size() > 0){string fuhao = temp.at(temp.size() - 1); //前一个while (IsLow(import[i], fuhao[0])){temp.pop_back();if (fuhao[0] == SUB && res_import.at(res_import.size() - 1)[0] == SUB){res_import.at(res_import.size() - 1)[0] = '+';}res_import.push_back(fuhao);if (temp.size() <= 0)break;fuhao = temp.at(temp.size() - 1);}}//压入这个符号temp_fh = import[i];temp.push_back(temp_fh);}}//把整个数字压入 用于最后一个字符是数字的情况if (temp_str != ""){res_import.push_back(temp_str);temp_str = "";}//将符号全部取出for (; temp.size() > 0;){string fuhao = temp.at(temp.size() - 1); temp.pop_back();if (fuhao[0] == SUB && res_import.at(res_import.size() - 1)[0] == SUB){res_import.at(res_import.size() - 1)[0] = '+';}res_import.push_back(fuhao);if (temp.size() <= 0)break;fuhao = temp.at(temp.size() - 1);}//转换成功与否if (res_import.size() > 0)return true;elsereturn false;
}
void calculator::PutOut()
{cout << "计算结果为:" << outport.c_str() << endl;
}
bool calculator::IsLow(const char &a, const char &b)
{if (FirstCode(a) < FirstCode(b))return true;elsereturn false;
}
int calculator::FirstCode(const char &a)
{switch (a){case LIFE:case RIGHT:return 0;case THEPOW:return 9;case JIECHENG:return 8;case MUL:return 5;case DIV:return 6;case ADD:return 2;case SUB:return 3;}return 0;
}
void calculator::GetResult()
{outport = "";vector<string> temp; //用于临时计算结果用的栈string temp_str = "";//临时存储数字for (int i = 0; i < res_import.size(); i++){if (res_import[i][0] == JIECHENG)  //如果是阶乘 则只需要一元{if (temp.size() < 1)return ;string res = DoCalculator(temp[temp.size() - 1], "", res_import[i][0]);if (res == "")return ;temp.pop_back();   //弹出上一个数字temp.push_back(res); //压入计算后的结果}else if (res_import[i][0] == THEPOW || res_import[i][0] == MUL || res_import[i][0] == DIV || res_import[i][0] == ADD || res_import[i][0] == SUB){if (temp.size() < 2)return ;string res = DoCalculator(temp[temp.size() - 2], temp[temp.size() - 1], res_import[i][0]);if (res == "")return ;temp.pop_back();    //弹出上一个数字temp.pop_back();    //弹出上一个数字temp.push_back(res);//压入计算后的结果}else  //数字{//直接压入临时栈temp.push_back(res_import[i]);}}outport = temp[0];return ;
}
string calculator::DoCalculator(const string &a, const string &b, const char &fuhao)
{double the_res = 0;switch (fuhao){case JIECHENG:break;case THEPOW:the_res = pow(atof(a.c_str()), atof(b.c_str()));break;case MUL:the_res = atof(a.c_str())*atof(b.c_str());break;case DIV:the_res = atof(a.c_str()) / atof(b.c_str());break;case ADD:the_res = atof(a.c_str()) + atof(b.c_str());break;case SUB:the_res = atof(a.c_str()) - atof(b.c_str());break;}char buffer[1024];sprintf_s(buffer, "%f\0", the_res);string str(buffer);return str;
}int main()
{calculator cal;cout << "请输入公式:" << endl;while (!cal.PutIn() || !cal.Change()){cout << "输入有误,请重新输入" << endl;}cal.GetResult();cal.PutOut();system("pause");return 0;
}
</pre>

附上运行结果截图:

以上就是做出普通计算器的过程(截至此仅为测试 所以我没有写上阶乘的循环,如果仅需要在double型范围内 则可自行补充即可使用)
前面我说了,我要做的是支持大数计算的,所以,接下去我们要稍作修改,把计算改为字符串类型的计算,这样就可以了。
思路:
我们可以想想我们用笔算的时候,是如何计算出加减乘除的。
加法:对齐小数点,小数部分先相加,从最后一位开始加起,如果超过进制,就向前进1,逐位计算。
换成大数计算的话,我们可以不必每一个数字为一位,我们可以多个数字为一位,如4个数字为一位,就是10000进制。所以我们可以先对字符串进行处理。将整数部分的前面补0对齐,小数部分的后面补0对齐,然后分割成每4位数为一个int的vector,这样就可以跟笔算一样计算下去,多少位都不怕!当然 要先判断正负号。如果一负一正 则转换为减法。如果两个都是负数 则得数前面要加-号。
减法:同理,减法也是要先对齐。不过 有个地方要注意,正负号取出,先判断两个数都为正的时候谁比较大,都是用比较大的数去减小的数。最后再去判断正负号的问题。减法也是一位位计算,如果不够减了,就向前面一位借1,以此类推。
乘法:每位循环相乘,结果相加。就跟我们笔算一样的概念。做出加法以后 乘法就很简单了。就不详细写了。记住负负得正 正负得负。
除法:除法比较难。按最简单暴力的方法,就是将有小数的数字转换为整数。然后用除数一直去减被除数。直到得数为0。这个是可以解决任意两个数相除的,但是有个问题,就是如果是除以1 那么要循环N次减法 这样效率就坑爹了。于是 我们先进行一个判断,先判断被除数有没有大于9位数。如果没有的话,我们可以将除数每9位分割,然后分别去除再相加。我们1234/5678 其实 等于 (1/5678) * 10^3+(2/5678) * 10^2+(3/5678) * 10^1+(4/5678) * 10^0 这样,就可以较快的计算了。
至于阶乘次方这些 基本的加减乘除出来以后,就迎刃而解了!
总结,需要注意以下几点:
1.小数部分和整数部分需要分开
2.正负号在处理数字之前判断,所有计算 都整理为正数进行计算会好些
3.不要使用每一个字符为一位进行计算!效率低得可怕!
4.该补0的要注意补0
5.位数分割要合理,我这边是以每4个字符为一位来处理,因为我用的vector<int>来处理,如果用64位的 则可以设置大点
代码如下:
#include<iostream>
#include<vector>
#include<string>
#include<cstdio>
#include<ctime>using namespace std;#define LEFT '('
#define RIGHT ')'
#define THPOWER '^'
#define FACTORIAL '!'
#define MUL '*'
#define DIV '/'
#define ADD '+'
#define SUB '-'
#define MINUS '#'
#define DIGIT 4
#define ARY 10000 //计算器类
class calculator
{
private:string import; //输入string outport; //输出vector<string> res_import; //转换后的输入public:calculator();~calculator();//输入 bool PutIn();//将输入的公式转换成逆波兰形式存储到vectorbool Change();//得到结果void GetResult();//输出void PutOut();//计算string DoCalculator(const string &a, const string &b, const char &fuhao);//优先级判断 是否低于前面bool IsLow(const char &a, const char &b);//优先级计算int FirstCode(const char &a);//字符串分成整数和小数部分void DoCalBase(const string &a, const string &b, vector<int> &int_a_i, vector<int> &int_b_i, vector<int> &int_a_f, vector<int> &int_b_f);//字符串对其补0 void DoToAlign(vector<int> &int_a_i, vector<int> &int_b_i, vector<int> &int_a_f, vector<int> &int_b_f);//字符串去掉.void DoToDelPoint(int &n, const string &a, const string &b, vector<int> &int_a_i, vector<int> &int_b_i);//去掉前面的0void DoDelFront(string &a);//去掉后面的0void DoDelBack(string &a);//将两个数字都化为整数(给除法用)void DoToBeInt(const string &a, const string &b, string &str_a_i, string &str_b_i);//加string DoAdd(const string &a, const string &b);//减string DoSub(const string &a, const string &b);//乘string DoMul(const string &a, const string &b);//除string DoDiv(const string &a, const string &b);//次方string DoTHPOWER(const string &a, const string &b);//阶乘string DoFACTORIAL(const string &a);//负号string DoNegativeNumber(const string &a);
};calculator::calculator() :import(""), outport(""), res_import(NULL)
{}
calculator::~calculator()
{}
bool calculator::PutIn()
{import = "";getline(cin, import);if (import == "")return false;elsereturn true;
}
bool calculator::Change()
{vector<string> temp; //用来临时存储操作符号的string temp_str = ""; //用来临时存储数字for (int i = 0; i < import.size(); i++){string temp_minus = "";//数字if ((import[i] >= '0' && import[i] <= '9') || import[i] == '.'){temp_str.push_back(import[i]);}else if (import[i] == LEFT){if (i > 0 && import[i - 1] != LEFT && import[i - 1] != THPOWER && import[i - 1] && FACTORIAL && import[i - 1] != MUL && import[i - 1] != DIV && import[i - 1] != ADD && import[i - 1] != SUB && import[i - 1] != MINUS){if (temp_str != ""){res_import.push_back(temp_str);temp_str = "";}temp.push_back("*");}temp_minus = import[i];temp.push_back(temp_minus);}else if (import[i] == RIGHT){//把整个数字压入if (temp_str != ""){res_import.push_back(temp_str);temp_str = "";}//弹出括号里面的符号if (temp.size() > 0){string fuhao = temp.at(temp.size() - 1);while (fuhao[0] != LEFT){temp.pop_back();res_import.push_back(fuhao);if (temp.size() <= 0)break;fuhao = temp.at(temp.size() - 1);}//弹出左括号temp.pop_back();}}else if (import[i] == THPOWER || import[i] == FACTORIAL || import[i] == MUL || import[i] == DIV || import[i] == ADD || import[i] == SUB || import[i] == MINUS){//把整个数字压入if (temp_str != ""){res_import.push_back(temp_str);temp_str = "";}//如果是负数 则特殊处理if (import[i] == SUB){if (i == 0 || import[i - 1] == LEFT ||  import[i - 1] == ADD ||  import[i - 1] == SUB ||  import[i - 1] == MUL ||  import[i - 1] == DIV ||  import[i - 1] == THPOWER ||  import[i - 1] == FACTORIAL ||  import[i - 1] == MINUS ){//压入#代表负数符号import[i] = MINUS;}}//判断优先级 如果比前面的低 则弹出前面一个if (temp.size() > 0){string fuhao = temp.at(temp.size() - 1); //前一个while (IsLow(import[i], fuhao[0])){temp.pop_back();if (fuhao[0] == SUB && res_import.at(res_import.size() - 1)[0] == SUB){res_import.at(res_import.size() - 1)[0] = '+';}res_import.push_back(fuhao);if (temp.size() <= 0)break;fuhao = temp.at(temp.size() - 1);}}//压入这个符号temp_minus = import[i];temp.push_back(temp_minus);}}//把整个数字压入 用于最后一个字符是数字的情况if (temp_str != ""){res_import.push_back(temp_str);temp_str = "";}//将符号全部取出for (; temp.size() > 0;){string fuhao = temp.at(temp.size() - 1); temp.pop_back();if (fuhao[0] == SUB && res_import.at(res_import.size() - 1)[0] == SUB){res_import.at(res_import.size() - 1)[0] = '+';}res_import.push_back(fuhao);if (temp.size() <= 0)break;fuhao = temp.at(temp.size() - 1);}//转换成功与否if (res_import.size() > 0)return true;elsereturn false;
}
void calculator::PutOut()
{cout << "计算结果为:" << outport.c_str() << endl;
}
bool calculator::IsLow(const char &a, const char &b)
{if (FirstCode(a) < FirstCode(b))return true;elsereturn false;
}
int calculator::FirstCode(const char &a)
{switch (a){case LEFT:case RIGHT:return 0;case THPOWER:return 9;case FACTORIAL:return 8;case MUL:return 5;case DIV:return 6;case ADD:return 2;case SUB:return 3;case MINUS:return 9;}return 0;
}
void calculator::GetResult()
{outport = "";vector<string> temp; //用于临时计算结果用的栈string temp_str = "";//临时存储数字for (int i = 0; i < res_import.size(); i++){if (res_import[i][0] == FACTORIAL || res_import[i][0] == MINUS )  //如果是阶乘或者符号 则只需要一元{if (temp.size() < 1)return ;string res = DoCalculator(temp[temp.size() - 1], "", res_import[i][0]);if (res == "")return ;temp.pop_back();  //弹出上一个数字temp.push_back(res); //压入计算后的结果}else if (res_import[i].size() == 1 && (res_import[i][0] == THPOWER || res_import[i][0] == MUL || res_import[i][0] == DIV || res_import[i][0] == ADD || res_import[i][0] == SUB)){if (temp.size() < 2)return ;string res = DoCalculator(temp[temp.size() - 2], temp[temp.size() - 1], res_import[i][0]);if (res == "")return ;temp.pop_back();    //弹出上一个数字temp.pop_back();    //弹出上一个数字temp.push_back(res);//压入计算后的结果}else  //数字{//直接压入临时栈temp.push_back(res_import[i]);}}outport = temp[0];return ;
}
string calculator::DoCalculator(const string &a, const string &b, const char &fuhao)
{string the_res = "";switch (fuhao){case MINUS:the_res = DoNegativeNumber(a);break;case FACTORIAL:the_res = DoFACTORIAL(a);break;case THPOWER:the_res = DoTHPOWER(a,b);break;case MUL:the_res = DoMul(a, b);break;case DIV:the_res = DoDiv(a, b);break;case ADD:the_res = DoAdd(a, b);break;case SUB:the_res = DoSub(a, b);break;}return the_res;
}
void calculator::DoCalBase(const string &a, const string &b, vector<int> &int_a_i, vector<int> &int_b_i, vector<int> &int_a_f, vector<int> &int_b_f)
{string str_a_i = "";string str_b_i = "";string str_a_f = "";string str_b_f = "";int_a_i.clear();int_b_i.clear();int_a_f.clear();int_b_f.clear();//把数字的整数和小数部分分别分割bool is_i = true;for (int i = 0; i < a.size(); i++){if (a[i] == '-')continue;if (a[i] == '.'){is_i = false;continue;}if (is_i){str_a_i += a[i];}else{str_a_f += a[i];}}is_i = true;for (int i = 0; i < b.size(); i++){if (b[i] == '-')continue;if (b[i] == '.'){is_i = false;continue;}if (is_i){str_b_i += b[i];}else{str_b_f += b[i];}}//将小数部分对齐 DoDelBack(str_a_f);DoDelBack(str_b_f);int f_max = str_a_f.size() - str_b_f.size();if (f_max > 0){for (int i = 0; i < f_max; i++){str_b_f = str_b_f + "0";}}else if (f_max < 0){f_max = -f_max;for (int i = 0; i < f_max; i++){str_a_f = str_a_f + "0";}}int bunumber = str_a_f.size() % DIGIT;if (bunumber > 0){for (int i = 0; i < DIGIT - bunumber; i++){str_a_f = str_a_f + "0";str_b_f = str_b_f + "0";}}//每N位分割int number = str_a_i.size() / DIGIT + 1; //多少个元素int count = str_a_i.size() % DIGIT;  //第一个元素有多少个字符string str_temp = "";int now_count = 0;for (; now_count < count; now_count++){str_temp = str_temp + str_a_i[now_count];}if (str_temp != ""){int_a_i.push_back(atoi(str_temp.c_str()));str_temp = "";}for (int j = 1; j < number; j++){bool is_push = false;for (int i = 0; i < DIGIT; i++, now_count++){if (str_a_i[now_count] != '0')is_push = true;if (is_push)str_temp = str_temp + str_a_i[now_count];}if (str_temp == "")str_temp = "0";int_a_i.push_back(atoi(str_temp.c_str()));str_temp = "";}number = str_b_i.size() / DIGIT + 1; //多少个元素count = str_b_i.size() % DIGIT;  //第一个元素有多少个字符str_temp = "";now_count = 0;for (; now_count < count; now_count++){str_temp = str_temp + str_b_i[now_count];}if (str_temp != ""){int_b_i.push_back(atoi(str_temp.c_str()));str_temp = "";}for (int j = 1; j < number; j++){bool is_push = false;for (int i = 0; i < DIGIT; i++, now_count++){if (str_b_i[now_count] != '0')is_push = true;if (is_push)str_temp = str_temp + str_b_i[now_count];}if (str_temp == "")str_temp = "0";int_b_i.push_back(atoi(str_temp.c_str()));str_temp = "";}//fnumber = str_a_f.size() / DIGIT + 1; //多少个元素count = str_a_f.size() % DIGIT;  //第一个元素有多少个字符str_temp = "";now_count = 0;for (; now_count < count; now_count++){str_temp = str_temp + str_a_f[now_count];}if (str_temp != ""){int_a_f.push_back(atoi(str_temp.c_str()));str_temp = "";}for (int j = 1; j < number; j++){bool is_push = false;for (int i = 0; i < DIGIT; i++, now_count++){if (str_a_f[now_count] != '0')is_push = true;if (is_push)str_temp = str_temp + str_a_f[now_count];}if (str_temp == "")str_temp = "0";int_a_f.push_back(atoi(str_temp.c_str()));str_temp = "";}number = str_b_f.size() / DIGIT + 1; //多少个元素count = str_b_f.size() % DIGIT;  //第一个元素有多少个字符str_temp = "";now_count = 0;for (; now_count < count; now_count++){str_temp = str_temp + str_b_f[now_count];}if (str_temp != ""){int_b_f.push_back(atoi(str_temp.c_str()));str_temp = "";}for (int j = 1; j < number; j++){bool is_push = false;for (int i = 0; i < DIGIT; i++, now_count++){if (str_b_f[now_count] != '0')is_push = true;if (is_push)str_temp = str_temp + str_b_f[now_count];}if (str_temp == "")str_temp = "0";int_b_f.push_back(atoi(str_temp.c_str()));str_temp = "";}
}
//字符串对其补0
void calculator::DoToAlign(vector<int> &int_a_i, vector<int> &int_b_i, vector<int> &int_a_f, vector<int> &int_b_f)
{int i_max = int_a_i.size() - int_b_i.size();if (i_max > 0){for (int i = 0; i < i_max; i++){int_b_i.insert(int_b_i.begin(), 0);}}else if (i_max < 0){i_max = -i_max;for (int i = 0; i < i_max; i++){int_a_i.insert(int_a_i.begin(), 0);}}int f_max = int_a_f.size() - int_b_f.size();if (f_max > 0){for (int i = 0; i < f_max; i++){int_b_f.push_back(0);}}else if (f_max < 0){f_max = -f_max;for (int i = 0; i < f_max; i++){int_a_f.push_back(0);}}
}
//去掉小数点 记录以后小数点要在倒数第几个
void calculator::DoToDelPoint(int &n, const string &a, const string &b, vector<int> &int_a_i, vector<int> &int_b_i)
{n = 0;string str_a_i = "";string str_b_i = "";int_a_i.clear();int_b_i.clear();bool is_dian = false;for (int i = 0; i < a.size(); i++){if (a[i] == '.'){is_dian = true;continue;}if (is_dian)n++;str_a_i += a[i];}is_dian = false;for (int i = 0; i < b.size(); i++){if (b[i] == '.'){is_dian = true;continue;}if (is_dian)n++;str_b_i += b[i];}DoDelFront(str_a_i);DoDelFront(str_b_i);//每N位分割int number = str_a_i.size() / DIGIT + 1; //多少个元素int count = str_a_i.size() % DIGIT;  //第一个元素有多少个字符string str_temp = "";int now_count = 0;for (; now_count < count; now_count++){str_temp = str_temp + str_a_i[now_count];}if (str_temp != ""){int_a_i.push_back(atoi(str_temp.c_str()));str_temp = "";}for (int j = 1; j < number; j++){bool is_push = false;for (int i = 0; i < DIGIT; i++, now_count++){if (str_a_i[now_count] != '0')is_push = true;if (is_push)str_temp = str_temp + str_a_i[now_count];}if (str_temp == "")str_temp = "0";int_a_i.push_back(atoi(str_temp.c_str()));str_temp = "";}number = str_b_i.size() / DIGIT + 1; //多少个元素count = str_b_i.size() % DIGIT;  //第一个元素有多少个字符str_temp = "";now_count = 0;for (; now_count < count; now_count++){str_temp = str_temp + str_b_i[now_count];}if (str_temp != ""){int_b_i.push_back(atoi(str_temp.c_str()));str_temp = "";}for (int j = 1; j < number; j++){bool is_push = false;for (int i = 0; i < DIGIT; i++, now_count++){if (str_b_i[now_count] != '0')is_push = true;if (is_push)str_temp = str_temp + str_b_i[now_count];}if (str_temp == "")str_temp = "0";int_b_i.push_back(atoi(str_temp.c_str()));str_temp = "";}
}
//给除法用
void calculator::DoToBeInt(const string &a, const string &b, string &str_a_i, string &str_b_i)
{int n1 = 0;int n2 = 0;str_a_i = "";str_b_i = "";bool is_dian = false;for (int i = 0; i < a.size(); i++){if (a[i] == '.'){is_dian = true;continue;}if (is_dian)n1++;str_a_i += a[i];}is_dian = false;for (int i = 0; i < b.size(); i++){if (b[i] == '.'){is_dian = true;continue;}if (is_dian)n2++;str_b_i += b[i];}DoDelFront(str_a_i);DoDelFront(str_b_i);//int n = n1 - n2;if(n > 0){for(int i = 0; i < n; i++){str_b_i.push_back('0');}}else if(n < 0){for(int i = 0; i < -n; i++){str_a_i.push_back('0');}}if(  str_a_i == "")str_a_i = "0";if(  str_b_i == "")str_b_i = "0";
}
//去掉前面的0
void calculator::DoDelFront(string &a)
{if (a.size() <= 0)return;while (a[0] == '0'){a.erase(a.begin());if (a.size() <= 0)return;}
}
//去掉后面的0
void calculator::DoDelBack(string &a)
{if (a.size() <= 0)return;while (a[a.size()-1] == '0'){a.erase(a.end() - 1);if (a.size() <= 0)return;}
}
//加法
string calculator::DoAdd(const string &a, const string &b)
{string f_str = "";string i_str = "";string is_fushu = "";vector<int> int_a_i; //a整数部分vector<int> int_a_f; //a小数部分vector<int> int_b_i; //b整数部分vector<int> int_b_f; //b小数部分string aa = a;string bb = b;if (a[0] == '-')aa.erase(aa.begin());if (b[0] == '-')bb.erase(bb.begin());if (a[0] == '-'){if (b[0] == '-'){is_fushu = "-";}else{return DoSub(bb, aa);}}else{if (b[0] == '-'){return DoSub(aa, bb);}}DoCalBase(aa, bb, int_a_i, int_b_i, int_a_f, int_b_f);DoToAlign(int_a_i, int_b_i, int_a_f, int_b_f);//每N位分别相加int temp = 0; //进位的数for (int i = int_a_f.size() - 1; i >= 0; i--){int res = int_a_f[i] + int_b_f[i] + temp;temp = int(res / ARY);char buffer[1024];sprintf_s(buffer, "%d\0", res % ARY);string str_temp(buffer);for (int x = str_temp.size(); x < DIGIT; x++){str_temp = "0" + str_temp;}f_str = str_temp + f_str;}for (int i = int_a_i.size() - 1; i >= 0; i--){int res = int_a_i[i] + int_b_i[i] + temp;temp = int(res / ARY);char buffer[1024];sprintf_s(buffer, "%d\0", res % ARY);string str_temp(buffer);for (int x = str_temp.size(); x < DIGIT; x++){str_temp = "0" + str_temp;}i_str = str_temp + i_str;}if (temp > 0){char buffer[1024];sprintf_s(buffer, "%d\0", temp % ARY);string str_temp(buffer);i_str = str_temp + i_str;temp = 0;}DoDelFront(i_str);DoDelBack(f_str);if (i_str == "")i_str = "0";if (f_str == "")f_str = "0";string res_str = "";if (f_str == "0")res_str = i_str;elseres_str = i_str + "." + f_str;if (is_fushu == "-")res_str = is_fushu + res_str;return res_str;
}
//减
string calculator::DoSub(const string &a, const string &b)
{string is_fushu = "";string f_str = "";string i_str = "";string aa = a;string bb = b;if (a[0] == '-')aa.erase(aa.begin());if (b[0] == '-')bb.erase(bb.begin());vector<int> int_a_i; //a整数部分vector<int> int_a_f; //a小数部分vector<int> int_b_i; //b整数部分vector<int> int_b_f; //b小数部分if (a[0] == '-'){if (b[0] == '-'){return DoSub(bb, aa);}else{return DoAdd(aa, bb);}}else {if (b[0] == '-'){return DoAdd(aa, bb);}}DoCalBase(aa, bb, int_a_i, int_b_i, int_a_f, int_b_f);DoToAlign(int_a_i, int_b_i, int_a_f, int_b_f);if (is_fushu == ""){for (int i = 0; i < int_a_i.size(); i++){if (int_a_i[i] < int_b_i[i]){is_fushu = "-";break;}else if (int_a_i[i] > int_b_i[i]){is_fushu = "+";break;}}}if (is_fushu == ""){for (int i = int_a_f.size() - 1; i >= 0; i--){if (int_a_f[i] < int_b_f[i]){is_fushu = "-";break;}else if (int_a_f[i] > int_b_f[i]){is_fushu = "+";break;}}}int temp = 0;if (is_fushu == "+"){for (int i = int_a_f.size() - 1; i >= 0; i--){int res = int_a_f[i] - temp - int_b_f[i];if (res < 0){res = res + ARY;temp = 1;}else{temp = 0;}char buffer[1024];sprintf_s(buffer, "%d\0", res);string str_temp(buffer);for (int x = str_temp.size(); x < DIGIT; x++){str_temp = "0" + str_temp;}f_str = str_temp + f_str;}for (int i = int_a_i.size() - 1; i >= 0; i--){int res = int_a_i[i] - temp - int_b_i[i];if (res < 0){res = res + ARY;temp = 1;}else{temp = 0;}char buffer[1024];sprintf_s(buffer, "%d\0", res);string str_temp(buffer);for (int x = str_temp.size(); x < DIGIT; x++){str_temp = "0" + str_temp;}i_str = str_temp + i_str;}}else if(is_fushu == "-"){for (int i = int_a_f.size() - 1; i >= 0; i--){int res = int_b_f[i] - temp - int_a_f[i];if (res < 0){res = res + ARY;temp = 1;}else{temp = 0;}char buffer[1024];sprintf_s(buffer, "%d\0", res);string str_temp(buffer);for (int x = str_temp.size(); x < DIGIT; x++){str_temp = "0" + str_temp;}f_str = str_temp + f_str;}for (int i = int_a_i.size() - 1; i >= 0; i--){int res = int_b_i[i] - temp - int_a_i[i];if (res < 0){res = res + ARY;temp = 1;}else{temp = 0;}char buffer[1024];sprintf_s(buffer, "%d\0", res);string str_temp(buffer);for (int x = str_temp.size(); x < DIGIT; x++){str_temp = "0" + str_temp;}i_str = str_temp + i_str;}}else{i_str = "0";f_str = "0";}DoDelFront(i_str);DoDelBack(f_str);if (i_str == "")i_str = "0";if (f_str == "")f_str = "0";string res_str = "";if (f_str == "0")res_str = i_str;elseres_str = i_str + "." + f_str;if (is_fushu == "-")res_str = is_fushu + res_str;return res_str;
}
//乘
string calculator::DoMul(const string &a, const string &b)
{string f_str = "";string i_str = "";string is_fushu = "";string aa = a;string bb = b;if (a[0] == '-')aa.erase(aa.begin());if (b[0] == '-')bb.erase(bb.begin());if (a[0] == '-' && b[0] != '-')is_fushu = "-";if (b[0] == '-' && a[0] != '-')is_fushu = "-";vector<int> int_a_i; //a整数部分vector<int> int_b_i; //b整数部分int n = 0;DoToDelPoint(n, aa, bb, int_a_i, int_b_i);for (int j = int_b_i.size() - 1; j >= 0; j--){string res_temp = "";int temp = 0;for (int i = int_a_i.size() - 1; i >= 0; i--){int res = int_a_i[i] * int_b_i[j] + temp;temp = int(res / ARY);char buffer[1024];sprintf_s(buffer, "%d\0", res % ARY);string str_temp(buffer);for (int x = str_temp.size(); x < DIGIT; x++){str_temp = "0" + str_temp;}res_temp = str_temp + res_temp;}if (temp > 0){char buffer[1024];sprintf_s(buffer, "%d\0", temp % ARY);string str_temp(buffer);res_temp = str_temp + res_temp;temp = 0;}DoDelFront(res_temp);if (res_temp != ""){for (int k = 0; k < int_b_i.size() - 1 - j; k++){string stemp = "";for (int x = 0; x < DIGIT; x++)stemp = stemp + "0";res_temp = res_temp + stemp;}i_str = DoAdd(i_str, res_temp);}}int i_str_size = i_str.size();if (i_str_size <= n){for (int i = i_str_size; i <= n; i++)i_str = "0" + i_str;}for (int i = 0; i < n; i++){f_str = i_str[i_str.size() - 1] + f_str;i_str.erase(i_str.end()-1);}DoDelFront(i_str);DoDelBack(f_str);if (i_str == "")i_str = "0";if (f_str == "")f_str = "0";string res_str = "";if (f_str == "0")res_str = i_str;elseres_str = i_str + "." + f_str;if (is_fushu == "-")res_str = is_fushu + res_str;return res_str;
}
//除
string calculator::DoDiv(const string &a, const string &b)
{string f_str = "";string i_str = "";string is_fushu = "";string res_str = "";string aa = a;string bb = b;if (a[0] == '-')aa.erase(aa.begin());if (b[0] == '-')bb.erase(bb.begin());if (a[0] == '-' && b[0] != '-')is_fushu = "-";if (b[0] == '-' && a[0] != '-')is_fushu = "-";string str_a_i; //a整数部分string str_b_i; //b整数部分DoToBeInt(aa, bb, str_a_i, str_b_i);{if(str_b_i.size() <= 9) //被除数如果在int范围内 则可以用除法去算.{int b_i = atoi(str_b_i.c_str());if(b_i == 0)return "0";string x = "1000000000";vector<int> int_a_i; //每9位分割 //每9位分割int number = str_a_i.size() / 9 + 1; //多少个元素int count = str_a_i.size() % 9;  //第一个元素有多少个字符string str_temp = "";int now_count = 0;for (; now_count < count; now_count++){str_temp = str_temp + str_a_i[now_count];}if (str_temp != ""){int_a_i.push_back(atoi(str_temp.c_str()));str_temp = "";}for (int j = 1; j < number; j++){bool is_push = false;for (int i = 0; i < 9; i++, now_count++){if (str_a_i[now_count] != '0')is_push = true;if (is_push)str_temp = str_temp + str_a_i[now_count];}if (str_temp == "")str_temp = "0";int_a_i.push_back(atoi(str_temp.c_str()));str_temp = "";}//计算for(int i = 0;i < int_a_i.size();i++){double res = double(int_a_i[i])/double(b_i);char buffer1[1024];sprintf_s(buffer1, "%lf\0", res);string str(buffer1);char buffer2[1024];sprintf_s(buffer2, "%d\0", int_a_i.size() - 1 - i);string cifang(buffer2);string thpower = DoTHPOWER(x, cifang);str = DoMul(str, thpower);res_str = DoAdd(res_str, str);}}else{string temp_a = str_a_i;int res = 0;int max_point = 100; // 最多小数点后100位int point = 0;while(1){if(temp_a == "0")break;if(point >= max_point){point--;break;}string temp = DoSub(temp_a, str_b_i);if(temp[0] == '-'){point++;char buffer[1024];sprintf_s(buffer, "%d\0", res);string str_temp(buffer);i_str = i_str + str_temp;res = 0;temp_a.push_back('0');}else{temp_a = temp;res++;}}if(res != 0){char buffer[1024];sprintf_s(buffer, "%d\0", res);string str_temp(buffer);i_str = i_str + str_temp;res = 0;}int i_str_size = i_str.size();if (i_str_size < point){for (int i = i_str_size; i <= point; i++)i_str = "0" + i_str;}for (int i = 0; i < point; i++){f_str = i_str[i_str.size() - 1] + f_str;i_str.erase(i_str.end()-1);}DoDelFront(i_str);DoDelBack(f_str);if (i_str == "")i_str = "0";if (f_str == "")f_str = "0";if (f_str == "0")res_str = i_str;elseres_str = i_str + "." + f_str;if (is_fushu == "-")res_str = is_fushu + res_str;}}return res_str;
}
//次方
string calculator::DoTHPOWER(const string &a, const string &b)
{string str = "";string aa = a;string bb = "";if(b[0] == '-')aa = DoDiv("1",aa);for(int i = 0; i < b.size();i++){if(b[i] == '.')break;if(b[i] >= '0' && b[i] <= '9')bb.push_back(b[i]);}if(bb == "")return str;if(bb == "0")return "1";int b_i = atoi(bb.c_str());for (int i = 0; i < b_i; i++){if (str == "")str = "1";str = DoMul(str, aa);}return str;
}
//阶乘
string calculator::DoFACTORIAL(const string &aa)
{string a = aa;string is_fushu = "";if(a[0] == '-'){a.erase(a.begin());is_fushu = "-";}string i_str = "1";int int_temp = 1;int int_end = atoi(a.c_str());if (int_end == 0){i_str = "";return i_str;}for (int i = 1; i < int_end;){i++;char buffer[1024];sprintf_s(buffer, "%d\0", i);string str_temp(buffer);i_str = DoMul(i_str, str_temp);}i_str = is_fushu + i_str;return i_str;
}
//负号
string calculator::DoNegativeNumber(const string &a)
{string str = "-";if(a[0] == '-'){str = a;str.erase(str.begin());}else {str = str + a;}return str;
}int main()
{calculator cal;cout << "请输入公式:" << endl;while (!cal.PutIn() || !cal.Change()){cout << "输入有误,请重新输入" << endl;}__int64 t1 = 0;__int64 t2 = 0;t1 = clock();cal.GetResult();t2 = clock();cal.PutOut();cout << endl << "用了 " << t2 - t1 << "ms" << endl;system("pause");return 0;
}

可以计算阶乘次方的大数计算器相关推荐

  1. python求阶乘之和_python计算阶乘前n项和

    广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 知道公式后就很简单了,利用for循环,第几行i+1就等于几,当然python中是 ...

  2. python怎么算阶乘_python专家写阶乘 ()用python计算阶乘

    请编写一个程序实现分享n的阶乘(即n.),并打印输出结果.要分享包括两个函def little_than_50(x): if x 语言很多时候是假的,一起经历过的事情才是真的. 这个用python写的 ...

  3. python怎么算阶乘_python计算阶乘

    广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 问题本身很简单,主要是通过这个小问题来演示python的一些用法,例如测试代码运 ...

  4. c语言计算阶乘的倒数和,for循环计算某个数的阶乘、阶乘和及其倒数的阶乘和...

    //4的阶乘 int jc = 4; //定义一个变量用来代表要计算的数值 long jd =1; //定义最终输出的阶乘 for(int i = 1; i <= jc;i++) //定义循环加 ...

  5. 5的2分之1怎么用计算机,【3558的二分之一次方怎么用计算器资讯】3558的二分之一次方怎么用计算器足球知识与常识 - 足球百科 - 599比分...

    如何用计算器算一个数的三分之二次方 如何用计算器算一个数的三分之二次方?方法一: 先把数(例如用p表示)p,平方(也就是二次方), 然后再开三次方(也就是3分之1次方). 开方,必须用<转换键& ...

  6. 打卡第二十四天(问题:计算阶乘,打印九九乘法表,计算最大公约数的两种算法)

    1.计算阶乘 这里给出递归和递推两种计算阶乘的程序. #include<stdio.h> //递归法计算阶乘 long factorial(int n) {if(n==0||n==1)re ...

  7. Python入门小项目-计算阶乘n的三种方法+常见练习(含代码示例)

    今天的文章主要给各位整理了Python常见的集中计算练习,这些也是作为初学者必会的联系项目了,代码分享出来,需要的朋友们可以看下~ 一.计算阶乘n! 整数的阶乘(英语:factorial)是所有小于及 ...

  8. 团体程序设计天梯赛-练习集L1-013. 计算阶乘和

    L1-013. 计算阶乘和 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 对于给定的正整数N,需要你计算 S = 1! + 2 ...

  9. python123阶乘累加_使用多线程计算阶乘累加 1!+2!+3!+...+19!+20!。其中一个线程计算阶乘,另一线程实现累加并输出结果。...

    运用多线程的信号灯法进行边加边计算!代码如下 public class JieChen { public static void main(String args[]){ Sum sum = new ...

最新文章

  1. MySQL - Join关联查询优化 --- NLJ及BNL 算法初探
  2. CF364B. Free Market
  3. linux原有的文件系统扩展,原来linux不用LVM也能扩展文件系统
  4. java知识回顾_Java7 –回顾
  5. Mac剪切板神器——Clipsy「记住999条剪贴板记录」
  6. 博图能打开s7200吗_域名掉备案了,还能打开吗?域名掉备案了怎么办?
  7. mysql带参数游标_mysql游标的使用
  8. Hive的下载,安装,配置以及连接的非常详细的过程
  9. java键值对_Java 读写键值对
  10. Java多线程面试攻略(一)
  11. imagej得到灰度图数据_Java图像处理最快技术:ImageJ 学习第一篇
  12. 合天网络靶场-大规模网络环境仿真服务平台
  13. 金融工程学(五):互换概述
  14. 教皇修改之后丢失的十天
  15. 【机器视觉】圆形测量
  16. 熊猫 PK27QA2 评测
  17. Nestjs中的守卫
  18. 剑指offer面试题之求第n个丑数
  19. ubuntu下离线侧扫声呐xtf格式数据提取软件
  20. 如何在OC类里 调用swift类

热门文章

  1. 中国的三种特色团购创新模式
  2. 首个搭载鸿蒙系统的手机,抢先P50,首款搭载鸿蒙系统的华为手机即将上市,是一款4G手机...
  3. 个人博客、开源文档的建站神仙组合 Vercel + Docusaurus
  4. 如何用计算机处理图片,修改图片用什么软件 小白必看的图片处理技巧_电脑故障...
  5. Loaded runtime CuDNN library,揭露NVIDIA的阴谋!!!
  6. 行测——逻辑推理——1三段论
  7. 7亿美元,京东上市前的最后一块踏板?
  8. 前端跨域请求原理及实践(加qq群:342430957)
  9. 歌者绮贞 花的姿态演唱会...
  10. 特斯拉电动卡车发布会背后:愿景、股价与产能