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;
}
``````

hijack00 回复S779876894N: 减法是一样的，借1当10。处理小数的时候，首先根据小数点对齐，没有的位数就补零。之后就和大整数的减法是一样的，大整数减法的模板也是可以找到的，即使找不到，其实现原理和加法也是类似的，只不过加法是进位，减法是借位。

S779876894N 回复hijack00: 大整数的模版是可以找到，可是自己根据代码改的程序还是不能实现小数的减法，加法是写出来了，减法只能实现整数，小数会出错。到处找不到小数的减法代码，自己写不出来啊

`````` #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;
}

``````
AlbertS 回复S779876894N: 你可以看看新代码有没有错误，我这里可以正常运行的

S779876894N 回复AlbertS: 下面传了

AlbertS 回复S779876894N: 你把错误截图传上来看看

AlbertS 回复S779876894N: 可以运行

S779876894N 回复AlbertS: 编译了一下有一个error，找不出来

S779876894N 测试可以运行吗，编译有1 error

AlbertS 回复S779876894N: 你那个可以运行了吗

AlbertS 回复S779876894N: VS2008

S779876894N 谢谢！你用的什么编辑器呀