根据逢十进一的规则,编程实现加法,用float,double定义时,多位小数精度丢失,如果采用字符串存储,且能输出超过6位的小数,用户输入的字符串非数字时直接结束程序,应该怎么编写,
引用chatGPT作答,以下是使用字符串实现逢十进一加法的C++代码:
#include <iostream>
#include <string>
using namespace std;
// 检查输入字符串是否为数字
bool isNumber(const string& s) {
for (char c : s) {
if (!isdigit(c) && c != '.' && c != '-') {
return false;
}
}
return true;
}
// 逢十进一加法
string add(string s1, string s2) {
// 找到两个字符串小数点的位置
int p1 = s1.find('.');
int p2 = s2.find('.');
// 如果s1没有小数点,则在末尾添加一个小数点
if (p1 == string::npos) {
s1 += '.';
p1 = s1.size() - 1;
}
// 如果s2没有小数点,则在末尾添加一个小数点
if (p2 == string::npos) {
s2 += '.';
p2 = s2.size() - 1;
}
// 找到两个字符串小数点后面的数字长度
int len1 = s1.size() - p1 - 1;
int len2 = s2.size() - p2 - 1;
// 在长度不足的小数后面补零,使它们的长度相等
if (len1 < len2) {
s1.append(len2 - len1, '0');
} else if (len1 > len2) {
s2.append(len1 - len2, '0');
}
// 对齐后的小数位数
int len = max(len1, len2);
// 进位标志
bool carry = false;
// 从小数点往前遍历,按逢十进一的规则相加
for (int i = len - 1; i >= 0; i--) {
// 如果当前位是小数点,则跳过
if (i == p1 || i == p2) {
continue;
}
// 计算当前位的数字和
int sum = (s1[i] - '0') + (s2[i] - '0') + (carry ? 1 : 0);
// 如果和大于等于10,则需要进位
if (sum >= 10) {
carry = true;
sum -= 10;
} else {
carry = false;
}
// 把当前位的和转成字符并存储到s1中
s1[i] = sum + '0';
}
// 如果最高位有进位,则在整数部分添加1
if (carry) {
s1.insert(0, "1");
}
// 把小数点插入到正确的位置
s1.insert(s1.size() - len, ".");
// 去掉字符串末尾多余的零
while (s1.back() == '0') {
s1.pop_back();
}
// 如果小数点后面没有数字,则去掉小数点
if (s1.back() == '.') {
s1.pop_back();
}
return s1;
}
int main() {
string s1, s2;
cout << "
// 循环读入两个字符串,直到两个字符串都是数字为止
while (true) {
cout << "请输入第一个数:";
getline(cin, s1);
if (isNumber(s1)) {
break;
}
cout << "输入错误,请重新输入!" << endl;
}
while (true) {
cout << "请输入第二个数:";
getline(cin, s2);
if (isNumber(s2)) {
break;
}
cout << "输入错误,请重新输入!" << endl;
}
// 调用逢十进一加法函数并输出结果
string result = add(s1, s2);
cout << "结果为:" << result << endl;
return 0;
这段代码中,isNumber
函数用于检查一个字符串是否为数字,其实现思路是遍历字符串中的每个字符,如果不是数字、小数点或负号,则返回false
,否则返回true
。add
函数用于进行逢十进一加法,其实现思路是先找到两个字符串的小数点位置,并在没有小数点的位置添加上一个小数点,然后在小数点后面补零,使两个字符串的小数位数相等,然后从小数点往前遍历,按逢十进一的规则相加,最后把小数点插入到正确的位置,并去掉多余的零。main
函数中,先循环读入两个字符串,直到两个字符串都是数字为止,然后调用add
函数进行加法运算,并输出结果。
注意,使用字符串进行逢十进一加法虽然可以保证多位小数的精度,但是效率比使用浮点数或双精度浮点数低。因此,在实际应用中,应根据需要选择合适的数据类型来进行计算。
运行结果如下:
可以使用字符串分割、转换和计算来实现加法运算,并使用异常处理来捕获用户输入非数字的情况。具体步骤如下:
定义一个函数 addition(),该函数接收两个字符串类型的数字,表示要相加的两个数。
在 addition() 函数内部,使用 stringstream 将输入的字符串转换为浮点数类型,然后将其分别存储在两个变量中。
使用 int() 函数将两个浮点数的整数部分相加,得到整数部分的和。
对于小数部分,可以使用取模和除法操作获取小数部分的整数部分和小数部分,然后将其相加。
如果小数部分的和大于等于10,则进位,并将进位后的数加到整数部分的和中。
最后,将相加后的结果转换为字符串类型,并返回给调用者。
在 addition() 函数中添加异常处理语句,如果用户输入的字符串不能转换为数字类型,则抛出异常并结束程序。
下面是具体的代码实现:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
string addition(string num1, string num2) {
try {
stringstream ss1(num1), ss2(num2);
double d1, d2;
ss1 >> d1;
ss2 >> d2;
int int_sum = int(d1) + int(d2);
double dec_sum = fmod(d1, 1) + fmod(d2, 1);
if (dec_sum >= 1) {
int_sum += 1;
dec_sum -= 1;
}
double result = int_sum + dec_sum;
stringstream ss;
ss.precision(10);
ss << fixed << result;
return ss.str();
}
catch (invalid_argument& e) {
cout << "输入不是数字,程序结束" << endl;
exit(1);
}
}
int main() {
string num1 = "12.3456789";
string num2 = "98.7654321";
cout << addition(num1, num2) << endl; // 111.1111110
return 0;
}
在上述代码中,使用了 fmod() 函数获取小数部分的整数部分和小数部分,并使用 stringstream 将相加后的结果转换为字符串类型。另外,程序在捕获到用户输入非数字的情况时,会输出一条错误提示信息,并通过 exit() 函数直接结束程序的运行。
#include<iostream>
#include<string>
#include<cctype>
#include<algorithm>
using namespace std;
string sum(string, string, string, string);
string sub(string, string, string, string);
bool main()
{
string num1, num2;
cout << "Input num1 , num2:" << endl;
cin >> num1 >> num2;
string num11, num12, num21, num22;
//输入检查
//是否是小数的标志
bool num1Flag = false, num2Flag = false;
for (auto c : num1)
{
//由数字或者数字加一个.组成
if (!isdigit(c) || num1.empty())
{
if (c == '.'&&!num1Flag)
{
num1Flag = true;
}
else
{
cout << "num1: Please input correct form!!!" << endl;
return false;
}
}
}
for (auto c : num2)
{
if (!isdigit(c) || num2.empty())
{
if (c == '.'&&!num2Flag)
{
num2Flag = true;
}
else
{
cout << "num2: Please input correct form!!!" << endl;
return 0;
}
}
}
//字符串分割{整数部分和小数部分)
if (num1Flag)//如果是小数
{
int i = 0;
while (i != num1.size() && num1[i] != '.')
{
num11 += num1[i];
++i;
}
while (++i != num1.size())
{
num12 += num1[i];
}
//用于.XXX或XXX.型输入的控制
if (num11.empty())
num11 += '0';
if (num12.empty())
num12 += '0';
}
else//如果是整数
{
num11 = num1;
num12 += '0';
}
if (num2Flag)//如果是小数
{
int i = 0;
while (i != num2.size() && num2[i] != '.')
{
num21 += num2[i];
++i;
}
while (++i != num2.size())
{
num22 += num2[i];
}
//用于.XXX或XXX.型输入的控制
if (num21.empty())
num21 += '0';
if (num22.empty())
num22 += '0';
}
else//如果是整数str
{
num21 = num2;
num22 += '0';
}
cout << "The Sum result = " << sum(num11, num12, num21, num22) << endl;
cout << "The Sub result = " << sub(num11, num12, num21, num22) << endl;
system("pause");
}
//加法 较长的整数部分 较长的小数部分 较短的整数部分 较短的小数部分
string sum(string strLong1, string strLong2, string strShort1, string strShort2)
{
//小数部分计算
if (strLong2.size()<strShort2.size())
{
string strTemp = strLong2;
strLong2 = strShort2;
strShort2 = strTemp;
}
//补0
for (int i = strShort2.size(); i<strLong2.size(); ++i)
strShort2 += '0';
//反转字符串
reverse(strLong2.begin(), strLong2.end());
reverse(strShort2.begin(), strShort2.end());
//小数部分进行加法计算
string strRes2(strLong2.size(), '0');
int carry = 0;//进位
for (int i = 0; i != strLong2.size(); ++i)
{
int a = strShort2[i] - '0', b = strLong2[i] - '0';
a = a + b + carry;
carry = a / 10;
strRes2[i] = (a % 10) + '0';
}
//反转回来
reverse(strRes2.begin(), strRes2.end());
//整数部分计算
if (strLong1.size()<strShort1.size())
{
string strTemp = strLong1;
strLong1 = strShort1;
strShort1 = strTemp;
}
//反转字符串
reverse(strLong1.begin(), strLong1.end());
reverse(strShort1.begin(), strShort1.end());
string strRes1(strLong1.size(), '0');
for (int i = 0; i != strShort1.size(); ++i)
{
int a = strShort1[i] - '0', b = strLong1[i] - '0';
a = a + b + carry;
carry = a / 10;
strRes1[i] = (a % 10) + '0';
}
for (int i = strShort1.size(); i != strLong1.size(); ++i)
{
int b = strLong1[i] - '0';
b += carry;
carry = b / 10;
strRes1[i] = b % 10 + '0';
}
if (carry)
{
strRes1 += (carry + '0');
}
//反转回来
reverse(strRes1.begin(), strRes1.end());
//合并整数部分和小数部分
string strRes = strRes1 + '.' + strRes2;
return strRes;
}
//减法 被减数的整数部分 被减数的小数部分 减数的整数部分 减数的小数部分
string sub(string strBjs1, string strBjs2, string strJs1, string strJs2)
{
//小数部分进行减法计算
int cntTemp = strBjs2.size() - strJs2.size();
//补0
if (cntTemp <= 0)
{
for (int i = cntTemp; i != 0; ++i)
{
strBjs2 += '0';
}
}
else
{
for (int i = cntTemp; i != 0; --i)
{
strJs2 += '0';
}
}
//反转字符串
reverse(strBjs2.begin(), strBjs2.end());
reverse(strJs2.begin(), strJs2.end());
string strRes2(strBjs2.size(), '0');
int carry = 0;//进位
for (int i = 0; i != strBjs2.size(); ++i)
{
int a = strBjs2[i] - '0', b = strJs2[i] - '0';
a = a - b - carry;
if (a >= 0)
{
carry = 0;
strRes2[i] = a + '0';
}
else
{
carry = 1;
strRes2[i] = a + 10 + '0';
}
}
//反转回来
reverse(strRes2.begin(), strRes2.end());
//整数部分进行减法计算
//反转字符串
reverse(strBjs1.begin(), strBjs1.end());
reverse(strJs1.begin(), strJs1.end());
string strRes1(strBjs1.size(), '0');
for (int i = 0; i != strJs1.size(); ++i)
{
int a = strBjs1[i] - '0', b = strJs1[i] - '0';
a = a - b - carry;
if (a >= 0)
{
carry = 0;
strRes1[i] = a + '0';
}
else
{
carry = 1;
strRes1[i] = a + 10 + '0';
}
}
for (int i = strJs1.size(); i != strBjs1.size(); ++i)
{
int a = strBjs1[i] - '0';
a = a - carry;
if (a >= 0)
{
carry = 0;
strRes1[i] = a + '0';
}
else
{
carry = 1;
strRes1[i] = a + 10 + '0';
}
}
if (carry)//此时除数比被除数大,结果为负数
{
return "*";
}
//反转回来
reverse(strRes1.begin(), strRes1.end());
//清楚冗余0
string strTemp;
cntTemp = 0;
for (int i = 0; strRes1[i] == '0'; ++i)++cntTemp;
for (int i = cntTemp; i != strRes1.size(); ++i)
strTemp += strRes1[i];
strRes1 = strTemp;
//合并整数部分和小数部分
string strRes = strRes1 + '.' + strRes2;
system("pause");
return strRes;
}
https://blog.csdn.net/zhuzhaoming1994/article/details/80343201
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
bool isNumber(const string& s) {
for (char c : s) {
if (!isdigit(c) && c != '.') {
return false;
}
}
return true;
}
int main() {
string str1, str2;
cout << "请输入第一个加数:" << endl;
cin >> str1;
if (!isNumber(str1)) {
cout << "输入非法!" << endl;
return 0;
}
cout << "请输入第二个加数:" << endl;
cin >> str2;
if (!isNumber(str2)) {
cout << "输入非法!" << endl;
return 0;
}
double num1 = stod(str1);
double num2 = stod(str2);
double sum = num1 + num2;
int intPart = (int)sum;
double decimalPart = sum - intPart;
if (decimalPart < 0.0) {
decimalPart = -decimalPart;
}
cout << "和为:" << intPart << ".";
for (int i = 0; i < 7; i++) {
decimalPart *= 10.0;
int digit = (int)decimalPart;
decimalPart -= digit;
cout << digit;
}
cout << endl;
return 0;
}
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main() {
string str1, str2;
cout << "请输入第一个加数:";
cin >> str1;
cout << "请输入第二个加数:";
cin >> str2;
// 判断输入是否为数字
stringstream ss1, ss2;
ss1 << str1;
ss2 << str2;
float num1, num2;
if (!(ss1 >> num1) || !(ss2 >> num2)) {
cout << "输入的不是数字!" << endl;
return 0;
}
float sum = num1 + num2;
printf("结果为:%.8f\n", sum);
return 0;
}
以下内容引用CHATGPT、有用望采纳:
在C++中,可以使用字符串来实现逢十进一加法。具体思路如下:
从用户输入中读取两个加数字符串num1和num2。
将num1和num2转换为整型数组,方便逐位相加。
从个位开始,逐位相加。每相加一位,判断是否需要进位,如果需要,则将进位后的值加入下一位的计算中。
将相加后的结果转换回字符串,并输出结果。
下面是一个简单的示例代码,可以参考。
#include <iostream>
#include <string>
using namespace std;
int main() {
string num1, num2;
cin >> num1 >> num2;
int len1 = num1.size(), len2 = num2.size();
int n1[len1], n2[len2];
for (int i = 0; i < len1; i++) {
n1[i] = num1[len1-i-1] - '0';
}
for (int i = 0; i < len2; i++) {
n2[i] = num2[len2-i-1] - '0';
}
int len = max(len1, len2);
int ans[len] = {0};
for (int i = 0; i < len; i++) {
ans[i] += n1[i] + n2[i];
if (ans[i] >= 10) {
ans[i+1] += ans[i] / 10;
ans[i] %= 10;
}
}
string result = "";
if (ans[len] != 0) {
result += ans[len] + '0';
}
for (int i = len-1; i >= 0; i--) {
result += ans[i] + '0';
}
cout << result << endl;
return 0;
}
注意:这个示例代码没有考虑非数字输入的情况,需要根据实际需求进行修改。
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
以下是C++代码实现逢十进一加法:
#include <iostream>
#include <string>
using namespace std;
string add(string num1, string num2)
{
int n1 = num1.size();
int n2 = num2.size();
string res = "";
int carry = 0;
int i = n1 - 1, j = n2 - 1;
while (i >= 0 || j >= 0 || carry)
{
int x = i >= 0 ? num1[i--] - '0' : 0;
int y = j >= 0 ? num2[j--] - '0' : 0;
int sum = x + y + carry;
carry = sum / 10;
sum %= 10;
res = to_string(sum) + res;
if (i >= 0 && i % 10 == 9 && j < 0 && carry == 0 && num1[i] != '0')
{
int q = i;
while (q >= 0 && num1[q] == '9') q--;
if (q < 0) res = "1" + res;
else res = num1[q] + 1 + res;
for (int k = q + 1; k <= i; k++) res = "0" + res;
break;
}
else if (j >= 0 && j % 10 == 9 && i < 0 && carry == 0 && num2[j] != '0')
{
int q = j;
while (q >= 0 && num2[q] == '9') q--;
if (q < 0) res = "1" + res;
else res = num2[q] + 1 + res;
for (int k = q + 1; k <= j; k++) res = "0" + res;
break;
}
}
while (res.size() > 1 && res[0] == '0') res.erase(0, 1);
return res;
}
int main()
{
string num1, num2;
cin >> num1 >> num2;
for (int i = 0; i < num1.size(); i++)
{
if (num1[i] < '0' || num1[i] > '9')
return 0;
}
for (int i = 0; i < num2.size(); i++)
{
if (num2[i] < '0' || num2[i] > '9')
return 0;
}
string res = add(num1, num2);
cout << res << endl;
return 0;
}
这里采用字符串存储,进行加法运算。在加法运算中,如果遇到需要进位的情况,根据题目要求,需要检查当前位是否是第10位,如果是第10位则需要进位,将前面一位加1。同时,需要考虑到add函数的返回值可能为超过6位的小数,保留这个精度可以通过string类型存储实现。用户输入的字符串非数字时直接结束程序,这里我们可以通过一个循环,遍历用户输入的字符串中的每个字符,如果有非数字字符,那么就结束程序。
如果我的回答解决了您的问题,请采纳!