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

本文介绍了如何使用自定义头文件‘BigDec.h’实现大浮点数的加、减、乘法操作。通过具体的代码实例,详细阐述了大数值计算的逻辑和方法,为处理高精度浮点数运算提供了参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值