头文件名称:”BigDec.h”
#ifndef BIGDEC_H_INCLUDED
#define BIGDEC_H_INCLUDED
#include <string>
using namespace std;
class BigDec
{
private:
vector<int> inte;//存储小数点前的数位,越往左,索引越大
vector<int> doub;//存储小数点后数位,越往右,索引越大
//索引例:3210.0123
int flag;//如果flag为-1则为负,1则为正,0则代表这个数为0
int AddTrans(BigDec &a1, BigDec &a2)//全变为同符号数加同符号数形式
{
if (a1.flag == 1 && a2.flag == -1) {
a2.flag = 1;
Minus (a1, a2);
a2.flag = -1;//不能忘记减完之后再换回来
return 0;
}
if (a1.flag == -1 && a2.flag == 1) {
a1.flag = 1;
Minus (a2, a1);
a1.flag = -1;
return 0;
}
if (a1.flag == 0) {
inte = a2.inte;
doub = a2.doub;
flag = a2.flag;
return 0;
}
if (a2.flag == 0) {
inte = a1.inte;
doub = a1.doub;
flag = a1.flag;
return 0;
}
return 1;
}
int MinusTrans(BigDec &a1, BigDec &a2)//全变为正数或0减正数或0
{
//全变为正数-正数形式
if (a1.flag == 1 && a2.flag == -1) {
a2.flag = 1;
Add (a1, a2);
a2.flag = -1;
return 0;
}
if (a1.flag == -1 && a2.flag == 1) {
a2.flag = -1;
Add (a1, a2);
a2.flag = 1;
return 0;
}
if (a1.flag == -1 && a2.flag == -1) {
a1.flag = 1;
a2.flag = 1;
Minus (a2, a1);
a1.flag = -1;
a2.flag = -1;
return 0;
}
return 1;
}
void DelZero()
{
//删除前导0
int l1 = inte.size();
for (int i = l1 - 1; i >= 0; i--) {
if (inte[i] == 0) inte.pop_back();
else break;
}
l1 = inte.size();
if (l1 == 0) inte.push_back (0);
//删除末尾的0
int l2 = doub.size();
for (int i = l2 - 1; i >= 0; i--) {
if (doub[i] == 0) doub.pop_back();
else break;
}
}
public:
void operator = (BigDec c)
{
inte = c.inte;
doub = c.doub;
flag = c.flag;
}
int Compare (BigDec c)//返回1则比c小
{
if (flag == 1) {
if (c.flag == -1 || c.flag == 0) return -1;
int l1 = inte.size();
int l2 = c.inte.size();
if (l1 < l2) return 1;
if (l1 > l2) return -1;
for (int i = l1 - 1; i >= 0; i--) {
if (inte[i] < c.inte[i]) return 1;
if (inte[i] > c.inte[i]) return -1;
}
l1 = doub.size();
l2 = c.doub.size();
int l = min (l1, l2);
for (int i = 0; i < l; i++) {
if (doub[i] < c.doub[i]) return 1;
if (doub[i] > c.doub[i]) return -1;
}
if (l1 != l) return -1;
if (l2 != l) return 1;
}
if (flag == 0) {
if (c.flag == 1) return 1;
if (c.flag == -1) return -1;
}
if (flag == -1) {
if (c.flag == 1 || c.flag == 0) return 1;
int l1 = inte.size();
int l2 = c.inte.size();
if (l1 < l2) return -1;
if (l1 > l2) return 1;
for (int i = l1 - 1; i >= 0; i--) {
if (inte[i] < c.inte[i]) return -1;
if (inte[i] > c.inte[i]) return 1;
}
l1 = doub.size();
l2 = c.doub.size();
int l = min (l1, l2);
for (int i = 0; i < l; i++) {
if (doub[i] < c.doub[i]) return -1;
if (doub[i] > c.doub[i]) return 1;
}
if (l1 != l) return 1;
if (l2 != l) return -1;
}
return 0;
}
void CreatDec(string s)//创建大浮点数类型
{
if (s[0] == '-') flag = -1;
else if (s[0] == '0') flag = 0;
else flag = 1;
int l = s.size();
int dot = l;//小数点的位置
for (int i = 0; i < l; i++) {
if (s[i] == '.') {
dot = i;
break;
}
}
for (int i = dot - 1; i >= 0; i--) {
if (s[i] == '-') break;
inte.push_back(s[i] - '0');
}
for (int i = dot + 1; i < l; i++) {
doub.push_back(s[i] - '0');
}
DelZero ();
}
void PrintDec()//打印大浮点数
{
int l1 = inte.size();
int l2 = doub.size();
if (flag == -1) printf ("-");
for (int i = l1 - 1; i >= 0; i--) {
printf ("%d", inte[i]);
}
if (l2 != 0) {//由于可能是整数,所以要判断一下
printf (".");
for (int i = 0; i < l2; i++) {
printf ("%d", doub[i]);
}
}
printf ("\n");
}
void Add(BigDec &a1, BigDec &a2)//a1+a2
{
if (AddTrans (a1, a2) == 0) return;
if (a1.flag == 1 && a2.flag == 1) flag = 1;
else flag = -1;
int li1 = a1.inte.size();
int ld1 = a1.doub.size();
int li2 = a2.inte.size();
int ld2 = a2.doub.size();
//加法运算的主函数段
//将长的那部分直接赋值给c
string s;
if (ld1 < ld2) {
for (int i = ld2 - 1; i >= ld1; i--) {
s += a2.doub[i] + '0';
}
}
if (ld1 > ld2) {
for (int i = ld1 - 1; i >= ld2; i--) {
s += a1.doub[i] + '0';
}
}
int ld = min (ld1, ld2);
int flag1 = 0;//如果flag1 == 1,则说明要进位
for (int i = ld - 1; i >= 0; i--) {
int temp = a1.doub[i] + a2.doub[i] + flag1;
if (temp / 10 != 0) flag1 = 1;
else flag1 = 0;
s += temp % 10 + '0';
}
int l = s.length();
for (int i = l - 1; i >= 0; i--) {
doub.push_back(s[i] - '0');
}
s.clear();
int li = min (li1, li2);
for (int i = 0; i < li; i++) {
int temp = a1.inte[i] + a2.inte[i] + flag1;
if (temp / 10 != 0) flag1 = 1;
else flag1 = 0;
inte.push_back(temp % 10);
}
if (li1 != li) {
for (int i = li; i < li1; i++) {
int temp = a1.inte[i] + flag1;
if (temp / 10 != 0) flag1 = 1;
else flag1 = 0;
inte.push_back(temp % 10);
}
}
if (li2 != li) {
for (int i = li; i < li2; i++) {
int temp = a2.inte[i] + flag1;
if (temp / 10 != 0) flag1 = 1;
else flag1 = 0;
inte.push_back(temp % 10);
}
}
if (flag1) inte.push_back(1);
DelZero ();
}
void Minus(BigDec &a1, BigDec &a2)//a1-a2
{
if (MinusTrans (a1, a2) == 0) return;
//处理0
if (a1.flag == 0 && a2.flag == 0) {
inte = a1.inte;
doub = a1.doub;
flag = a1.flag;
return;
}
if (a1.flag == 0) {
inte = a2.inte;
doub = a2.doub;
flag = -1;
return;
}
if (a2.flag == 0) {
inte = a1.inte;
doub = a1.doub;
flag = -1;
return;
}
int Test = a1.Compare(a2);
if (Test == 0) {
inte.push_back(0);
flag = 0;
return;
}
if (Test == -1) {//如果a1比a2大
flag = 1;
int li1 = a1.inte.size();
int li2 = a2.inte.size();
int ld1 = a1.doub.size();
int ld2 = a2.doub.size();
int ldmax = max (ld1, ld2);
if (ld1 < ldmax) {
for (int i = 0; i < ldmax - ld1; i++) {
a1.doub.push_back (0);
}
}
if (ld2 < ldmax) {
for (int i = 0; i < ldmax - ld2; i++) {
a2.doub.push_back (0);
}
}
int flag1 = 0;//如果flag1为1则说明要借位
//处理小数位
string s;
for (int i = ldmax - 1; i >= 0; i--) {
int temp = a1.doub[i] - a2.doub[i] - flag1;
if (temp < 0) {
temp += 10;
flag1 = 1;
} else {
flag1 = 0;
}
s += temp + '0';
}
int l = s.length();
for (int i = l - 1; i >= 0; i--) {
doub.push_back(s[i] - '0');
}
s.clear();
if (ld1 < ldmax) {
for (int i = 0; i < ldmax - ld1; i++) {
a1.doub.pop_back();
}
}
//处理整数位
int li = min (li1, li2);
for (int i = 0; i < li; i++) {
int temp = a1.inte[i] - a2.inte[i] - flag1;
if (temp < 0) {
temp += 10;
flag1 = 1;
} else {
flag1 = 0;
}
inte.push_back(temp);
}
if (li1 != li) {
for (int i = li; i < li1; i++) {
int temp = a1.inte[i] - flag1;
if (temp < 0) {
temp += 10;
flag1 = 1;
} else {
flag1 = 0;
}
inte.push_back(temp);
}
}
if (inte.size() == 0) inte.push_back(0);
DelZero();
return;
}
if (Test == 1) {
Minus (a2, a1);
flag = -1;
return;
}
}
void Multi(BigDec a1, BigDec a2)//a1*a2
{
flag = a1.flag * a2.flag;
int dot = a1.doub.size() + a2.doub.size();
string s, s1, s2;
int li1 = a1.inte.size();
int li2 = a2.inte.size();
int ld1 = a1.doub.size();
int ld2 = a2.doub.size();
for (int i = ld1 - 1; i >= 0; i--) {
s1 += a1.doub[i] + '0';
}
for (int i = 0; i < li1; i++) {
s1 += a1.inte[i] + '0';
}
for (int i = ld2 - 1; i >= 0; i--) {
s2 += a2.doub[i] + '0';
}
for (int i = 0; i < li2; i++) {
s2 += a2.inte[i] + '0';
}
int l1 = s1.length();
int l2 = s2.length();
int l = l1 + l2 + 1;
while (l--) {
s += '0';
}
for (int i = 0; i < l1; i++) {
for (int j = 0; j < l2; j++) {
int temp = (s1[i] - '0') * (s2[j] - '0') + s[i + j] - '0';
s[i + j] = temp % 10 + '0';
s[i + j + 1] += temp / 10;
}
}
l = s.length();
for (int i = dot - 1; i >= 0; i--) {
doub.push_back(s[i] - '0');
}
for (int i = dot; i < l; i++) {
inte.push_back(s[i] - '0');
}
if (inte.size() == 0) inte.push_back(0);
DelZero ();
}
};
#endif // BIGDEC_H_INCLUDED
具体应用实例:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
#include "BigDec.h"
using namespace std;
int main()
{
while(1) {
string s1, s2;
cout << "请输入第一个数:" << endl;
cin >> s1;
cout << "请输入第二个数:" << endl;
cin >> s2;
BigDec a1, a2;
a1.CreatDec (s1);
a2.CreatDec (s2);
while (1) {
cout << "求和输入1,求差输入2,求积输入3,重新输入数输入4,结束程序输入0"<< endl;
int flag = 0;
int dir;
cin >> dir;
switch (dir) {
case 0:return 0;
case 1:{
BigDec c1;
c1.Add (a1, a2);
c1.PrintDec ();
break;
}
case 2:{
BigDec c2;
c2.Minus (a1, a2);
c2.PrintDec ();
break;
}
case 3:{
BigDec c3;
c3.Multi (a1, a2);
c3.PrintDec ();
break;
}
case 4:{
flag = 1;
break;
}
default:{
cout << "输入错误,请重新输入" << endl;
}
}
if (flag) break;
}
}
return 0;
}