c++高精度小数减法问题

程序主要要求 主程序读入两个字符串类型的大数(小数),通过函数实现小数的高精度减法。求完整的代码和注释,比较急,谢谢

c c++

6个回答

你这是什么编辑器啊。连作用域都不分,我把变量名都改了,代码如下:

#include <iostream>
using namespace std;
#define MAX_NUMBER_LEN 1024

bool isGreaterThan(const int* pNum1, const int* pNum2)
{
    if (pNum1 == NULL || pNum2 == NULL)
    {
        cout << "您输入的数字有误" << endl;
        return false;
    }

    for(int nIndx = 0; nIndx < MAX_NUMBER_LEN; ++nIndx)
    {
        if (pNum1[nIndx] > pNum2[nIndx])
            return true;
    }

    return false;
}

int main()
{

    char szNum1[1024] = {0};
    char szNum2[1024] = {0};
    int arNumber1[1024] = {0};
    int arNumber2[1024] = {0};

    cout << "请输入两个小数(小数位数不要超过500位),空格分隔:" << endl;

    cin >> szNum1;
    cin >> szNum2;


    // 把第一个字符串转化成数组
    int nCount = 0;
    int nNumLen = strlen(szNum1);
    bool bFindDot = false;
    for (int nIndex = 0, pos = nIndex + 1; nIndex < nNumLen; ++nIndex)
    {
        if (szNum1[nIndex] == '.')
        {
            bFindDot = true;
        }
        else
        {
            if(szNum1[nIndex] < '0' || szNum1[nIndex] > '9')
            {
                cout << "请输入不是正确的数字" << endl;
                return 0;
            }
            else
            {   
                arNumber1[pos] = szNum1[nIndex] - '0';
            }
            pos++;

        }

        if (!bFindDot)
            nCount++;
    }
    arNumber1[0] = nCount;




    // 把第二个字符串转化成数组
    nCount = 0;
    nNumLen = strlen(szNum2);
    bFindDot = false;
    for (int nIndex1 = 0, pos = nIndex1 + 1; nIndex1 < nNumLen; ++nIndex1)
    {
        if (szNum2[nIndex1] == '.')
        {
            bFindDot = true;
        }
        else
        {
            if(szNum2[nIndex1] < '0' || szNum2[nIndex1] > '9')
            {
                cout << "请输入不是正确的数字" << endl;
                break;
            }
            else
            {   
                arNumber2[pos] = szNum2[nIndex1] - '0';
            }
            pos++;

        }

        if (!bFindDot)
            nCount++;
    }
    arNumber2[0] = nCount;


    bool isGreater = isGreaterThan(arNumber1, arNumber2);
    // 比较小数前的位数
    if (arNumber1[0] != arNumber2[0])
    {

        int nshift = abs(arNumber1[0] - arNumber2[0]);
        int *pNum;
        int nTotal;

        if(isGreater)
        {
            pNum = arNumber2;
            nTotal = strstr(szNum2, ".") ? strlen(szNum2) - 1 : strlen(szNum2);
        }
        else
        {
            pNum = arNumber1;
            nTotal = strstr(szNum1, ".") ? strlen(szNum1) - 1 : strlen(szNum1);
        }

        for(int nIndex2 = nTotal; nIndex2 >= 0; --nIndex2)
        {
            pNum[nIndex2 + nshift] = pNum[nIndex2];
        }

        for(int nIndex2 = nshift; nIndex2 >= 1; --nIndex2)
        {
            pNum[nIndex2] = 0;
        }
    }

    // 做简单减法
    int nlen1 = strstr(szNum1, ".") ? strlen(szNum1) - 1 : strlen(szNum1);
    int nlen2 = strstr(szNum2, ".") ? strlen(szNum2) - 1 : strlen(szNum2);
    int forcount= nlen1 > nlen2 ?nlen1 : nlen2;
    if (isGreater)
    {
        for (int nIndex3 = 1; nIndex3 <= forcount; nIndex3++)
        {
            arNumber1[nIndex3] = arNumber1[nIndex3] - arNumber2[nIndex3];
        }
    }
    else
    {
        for (int nIndex4 = 1; nIndex4 <= forcount; nIndex4++)
        {
            arNumber1[nIndex4] = arNumber2[nIndex4] - arNumber1[nIndex4];
        }

    }


    // 处理减法中的负数
    arNumber1[0]  = arNumber1[0] > arNumber2[0] ? arNumber1[0] : arNumber2[0];

    for ( int nIndex5 = forcount; nIndex5 > 0; --nIndex5)
    {
        if (arNumber1[nIndex5] < 0)
        {
            arNumber1[nIndex5] += 10;
            arNumber1[nIndex5 - 1] -= 1;
        }
    }


    cout << "结果为" << endl;
    if (!isGreater)
        cout << "-";


    //输出结果
    bool zerooutpput = false;
    bool putpucount = 0;
    for( int nIndex6 = 1; nIndex6 <= forcount; nIndex6++ )
    {
        if (arNumber1[nIndex6] != 0 || nIndex6 > arNumber1[0])
        {
            zerooutpput = true;
            cout << arNumber1[nIndex6];
            putpucount++;
        }
        else if (zerooutpput)
        {
            cout << arNumber1[nIndex6];
            putpucount++;
        }

        if (nIndex6 == arNumber1[0])
        {
            if (putpucount == 0)
                cout << "0";

            if (nIndex6 != forcount)
                cout << '.';
        }
    }


    system("pause");

    return 0;
} 

这个和BigInteger的加法减法是一样的原理,只不过小数减法要考虑小数点对齐,用STL中的deque容器实现应该比较简单,直接用C语言的数组也能做处理。你百度一下"C++ BigInteger"应该能找到示例代码

hijack00
hijack00 回复S779876894N: 减法是一样的,借1当10。处理小数的时候,首先根据小数点对齐,没有的位数就补零。之后就和大整数的减法是一样的,大整数减法的模板也是可以找到的,即使找不到,其实现原理和加法也是类似的,只不过加法是进位,减法是借位。
大约 4 年之前 回复
S779876894N
S779876894N 回复hijack00: 大整数的模版是可以找到,可是自己根据代码改的程序还是不能实现小数的减法,加法是写出来了,减法只能实现整数,小数会出错。到处找不到小数的减法代码,自己写不出来啊
大约 4 年之前 回复

写的有点仓促,凑活着看

 #include <iostream>
using namespace std;
#define MAX_NUMBER_LEN 1024

bool isGreaterThan(const int* pNum1, const int* pNum2)
{
    if (pNum1 == NULL || pNum2 == NULL)
    {
        cout << "您输入的数字有误" << endl;
        return false;
    }

    for(int nIndx = 0; nIndx < MAX_NUMBER_LEN; ++nIndx)
    {
        if (pNum1[nIndx] > pNum2[nIndx])
            return true;
    }

    return false;
}

int main()
{

    char szNum1[1024] = {0};
    char szNum2[1024] = {0};
    int arNumber1[1024] = {0};
    int arNumber2[1024] = {0};

    cout << "请输入两个小数(小数位数不要超过500位),空格分隔:" << endl;

    cin >> szNum1;
    cin >> szNum2;


    // 把第一个字符串转化成数组
    int nCount = 0;
    int nNumLen = strlen(szNum1);
    bool bFindDot = false;
    for (int nIndex = 0, pos = nIndex + 1; nIndex < nNumLen; ++nIndex)
    {
        if (szNum1[nIndex] == '.')
        {
            bFindDot = true;
        }
        else
        {
            if(szNum1[nIndex] < '0' || szNum1[nIndex] > '9')
            {
                cout << "请输入不是正确的数字" << endl;
                break;
            }
            else
            {   
                arNumber1[pos] = szNum1[nIndex] - '0';
            }
            pos++;

        }

        if (!bFindDot)
            nCount++;
    }
    arNumber1[0] = nCount;




    // 把第二个字符串转化成数组
    nCount = 0;
    nNumLen = strlen(szNum2);
    bFindDot = false;
    for (int nIndex = 0, pos = nIndex + 1; nIndex < nNumLen; ++nIndex)
    {
        if (szNum2[nIndex] == '.')
        {
            bFindDot = true;
        }
        else
        {
            if(szNum2[nIndex] < '0' || szNum2[nIndex] > '9')
            {
                cout << "请输入不是正确的数字" << endl;
                break;
            }
            else
            {   
                arNumber2[pos] = szNum2[nIndex] - '0';
            }
            pos++;

        }

        if (!bFindDot)
            nCount++;
    }
    arNumber2[0] = nCount;


    bool isGreater = isGreaterThan(arNumber1, arNumber2);
    // 比较小数前的位数
    if (arNumber1[0] != arNumber2[0])
    {

        int nshift = abs(arNumber1[0] - arNumber2[0]);
        int *pNum;
        int nTotal;

        if(isGreater)
        {
            pNum = arNumber2;
            nTotal = strlen(szNum2) -1;
        }
        else
        {
            pNum = arNumber1;
            nTotal = strlen(szNum1) -1;
        }

        for(int nIndex = nTotal; nIndex >= nshift; --nIndex)
        {
            pNum[nIndex + nshift] = pNum[nIndex];
        }

        for(int nIndex = nshift; nIndex >= 1; --nIndex)
        {
            pNum[nIndex] = 0;
        }
    }

    // 做简单减法
    int forcount= strlen(szNum1) > strlen(szNum2) ? (strlen(szNum1) - 1) : (strlen(szNum2) - 1);
    if (isGreater)
    {
        for (int nIndex = 1; nIndex <= forcount; nIndex++)
        {
            arNumber1[nIndex] = arNumber1[nIndex] - arNumber2[nIndex];
        }
    }
    else
    {
        for (int nIndex = 1; nIndex <= forcount; nIndex++)
        {
            arNumber1[nIndex] = arNumber2[nIndex] - arNumber1[nIndex];
        }

    }


    // 处理减法中的负数
    arNumber1[0]  = arNumber1[0] > arNumber2[0] ? arNumber1[0] : arNumber2[0];

    for ( int nIndex = forcount; nIndex > 0; --nIndex)
    {
        if (arNumber1[nIndex] < 0)
        {
            arNumber1[nIndex] += 10;
            arNumber1[nIndex - 1] -= 1;
        }
    }


    cout << "结果为" << endl;
    if (!isGreater)
        cout << "-";


    //输出结果
    bool zerooutpput = false;
    bool putpucount = 0;
    for( int nIndex = 1; nIndex <= forcount; nIndex++ )
    {
        if (arNumber1[nIndex] != 0 || nIndex > arNumber1[0])
        {
            zerooutpput = true;
            cout << arNumber1[nIndex];
            putpucount++;
        }
        else if (zerooutpput)
        {
            cout << arNumber1[nIndex];
            putpucount++;
        }

        if (nIndex == arNumber1[0])
        {
            if (putpucount == 0)
                cout << "0";
            cout << '.';
        }
    }


    system("pause");

    return 0;
}

shihengzhen101
AlbertS 回复S779876894N: 你可以看看新代码有没有错误,我这里可以正常运行的
大约 4 年之前 回复
S779876894N
S779876894N 回复AlbertS: 下面传了
大约 4 年之前 回复
shihengzhen101
AlbertS 回复S779876894N: 你把错误截图传上来看看
大约 4 年之前 回复
shihengzhen101
AlbertS 回复S779876894N: 可以运行
大约 4 年之前 回复
S779876894N
S779876894N 回复AlbertS: 编译了一下有一个error,找不出来
大约 4 年之前 回复
S779876894N
S779876894N 测试可以运行吗,编译有1 error
大约 4 年之前 回复

有些情况没有考虑到,可以发现了改一下

截图图片说明

这是运行截图
图片说明

shihengzhen101
AlbertS 回复S779876894N: 你那个可以运行了吗
大约 4 年之前 回复
shihengzhen101
AlbertS 回复S779876894N: VS2008
大约 4 年之前 回复
S779876894N
S779876894N 谢谢!你用的什么编辑器呀
大约 4 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐