较完备的大浮点数的加减乘法

来源:互联网 发布:淘宝页面背景图 编辑:程序博客网 时间:2024/06/16 06:04

头文件名称:”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;}
0 0