首页 > 试题广场 >

浮点数加法

[编程题]浮点数加法
  • 热度指数:18339 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
求2个浮点数相加的和 题目中输入输出中出现浮点数都有如下的形式: P1P2...Pi.Q1Q2...Qj 对于整数部分,P1P2...Pi是一个非负整数 对于小数部分,Qj不等于0

输入描述:
对于每组案例,每组测试数据占2行,分别是两个加数。


输出描述:
每组案例是n行,每组测试数据有一行输出是相应的和。
输出保证一定是一个小数部分不为0的浮点数
示例1

输入

0.111111111111111111111111111111
0.111111111111111111111111111111

输出

0.222222222222222222222222222222
#include<iostream>
#include<string>

using namespace std;
int main() {
    string a, b, a_integer, b_integer,a_decimal,b_decimal;
    int start_a, start_b,start;
    int a_integer_int, b_integer_int;
    int a_decimal_int, b_decimal_int;
    int carry = 0;
    while (getline(cin, a)) {
        getline(cin, b);
        start_a = a.find('.');
        start_b = b.find('.');
        //小数部分
        if (a.substr(start_a + 1, a.length() - start_a - 1).size() < b.substr(start_b + 1, b.length() - start_b - 1).size()) {
            string aa(b.substr(start_b + 1, b.length() - start_b - 1).size() - a.substr(start_a + 1, a.length() - start_a - 1).size(), '0');
            a = a + aa;
        }
        if (a.substr(start_a + 1, a.length() - start_a - 1).size() > b.substr(start_b + 1, b.length() - start_b - 1).size()) {
            string bb(a.substr(start_a + 1, a.length() - start_a - 1).size() - b.substr(start_b + 1, b.length() - start_b - 1).size(), '0');
            b = b + bb;
        }

        a_decimal = a.substr(start_a + 1, a.length() - start_a - 1);
        b_decimal = b.substr(start_b + 1, b.length() - start_b - 1);


        carry = 0;
        for (int i = a_decimal.size() - 1; i >= 0; i--) {
            a_decimal_int = a_decimal[i] - '0';
            b_decimal_int = b_decimal[i] - '0';
            if (a_decimal_int + b_decimal_int + carry <= 9) {
                a_decimal[i] = a_decimal_int + b_decimal_int + carry + '0';
                carry = 0;
            }
            else {
                a_decimal[i] = (a_decimal_int + b_decimal_int + carry) % 10 + '0';
                carry = 1;
            }
        }

        //整数部分
        start = start_b;
        if (a.substr(0, start_a).size() < b.substr(0, start_b).size()) {
           string aa(b.substr(0, start_b).size() - a.substr(0, start_a).size(), '0');
           a = aa + a;
           start = start_b;
        }
        if (a.substr(0, start_a).size() > b.substr(0, start_b).size()) {
            string bb(a.substr(0, start_a).size() - b.substr(0, start_b).size(), '0');
            b = bb + b;
            start = start_a;
        }
        
        a_integer = a.substr(0, start);
        b_integer = b.substr(0, start);


        for (int i = a_integer.size() - 1; i >= 0; i--) {
            a_integer_int = a_integer[i] - '0';
            b_integer_int = b_integer[i] - '0';
            if (a_integer_int + b_integer_int + carry <= 9) {
                a_integer[i] = a_integer_int + b_integer_int + carry + '0';
                carry = 0;
            }
            else {
                a_integer[i] = (a_integer_int + b_integer_int + carry) % 10 + '0';
                carry = 1;
            }
        }
        if (carry == 1) {
            cout << "1" + a_integer + "." + a_decimal;
        }
        else {
            cout <<  a_integer + "." + a_decimal;
        }
    }
    return 0;
}

发表于 2022-01-07 15:10:33 回复(1)
贡献一下子思路:
字符串高精度加法,分成整数和小数部分,自然是从小数那里从后往前一直算了
首先是补0和倒转数字,方法看不懂的话可以自己试着写个竖式加法,就很容易理解了,还没看明白的可以说下
1.对于小数:先补0再倒转
2.对于整数:先倒转再补0

其次就是开始运算了。定一个result字符串,这是返回的东西
1.对于小数:定一个判断是否进位的bool变量,然后:
(1)不需要进位:当前位的和转化为字符串(若和小于10)或者和减10再转字符串
(2)需要进位:上面说的和再加1

2.算完小数以后,给result加一个'.'

3.开始整数的高精度计算,这个跟上面类似就不重复说了。注意点有:
(1)要看前面判断小数计算是否要进位,如果要在算第一位整数和的时候要注意一下加1
(2)算到最后一位如果还有进位,给result加一个1

4.最后就是反转result,就是我们想要的结果了。
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
/*
 
 */
//把输入的数字字符串拆分两个,分别是整数部分和小数部分
vector<string> extract(string num){
    vector<string> extract_string;
    //整数和小数部分的str
    string int_str="";
    string float_str="";
    //记录小数点的位置
    int dot_pos=0;
    //提取整数部分
    for(int i=0;i<num.length();++i){
        if(num[i]=='.'){
            dot_pos=i;
            break;
        }
        else{
            int_str+=num[i];
        }
    }
    //提取小数部分
    for(int i=dot_pos+1;i<num.length();++i){
        float_str+=num[i];
    }
    //先放入整数部分,再放入小数部分
    extract_string.push_back(int_str);
    extract_string.push_back(float_str);
    return extract_string;
}
//浮点数字符串加法
string floatNumAdd(string &num1,string &num2){
    string result="";
    //分别记录两个数字的整数和小数部分
    vector<string> extract_num1=extract(num1);
    vector<string> extract_num2=extract(num2);
    string int_num1=extract_num1[0];
    string float_num1=extract_num1[1];
    string int_num2=extract_num2[0];
    string float_num2=extract_num2[1];
    int len_float=float_num1.length()>=float_num2.length()?float_num1.length():float_num2.length();
    int len_int=int_num1.length()>=int_num2.length()?int_num1.length():int_num2.length();
    //给小数少的补0,补完0再换顺序
    if(len_float==float_num1.length()){
        while(float_num2.length()!=len_float)
            float_num2+='0';
    }
    else{
        while(float_num1.length()!=len_float)
            float_num1+='0';
    }
    //补完0后t调换顺序
    reverse(float_num1.begin(), float_num1.end());
    reverse(float_num2.begin(), float_num2.end());
    
    //给整数部分补0,需要先调换过来
    reverse(int_num1.begin(), int_num1.end());
    reverse(int_num2.begin(), int_num2.end());
    //给短的那个加0
    if(len_int==int_num1.length()){
        while (int_num2.length()!=len_int) {
            int_num2+='0';
        }
    }
    else{
        while (int_num1.length()!=len_int) {
            int_num1+='0';
        }
    }
    
    //开始进行高精度加法
    //记录小数部分加法是否进位
    bool float_addExtra=false;
    for(int i=0;i<len_float;++i){
        if(float_addExtra==false){
            int n1=float_num1[i]-'0';
            int n2=float_num2[i]-'0';
            int sum=n1+n2;
            if(sum<10)result+=sum+'0';
            else{
                float_addExtra=true;
                result+=sum-10+'0';
            }
        }
        else{
            int n1=float_num1[i]-'0';
            int n2=float_num2[i]-'0';
            int sum=n1+n2+1;
            if(sum<10){
                float_addExtra=false;
                result+=sum+'0';
            }
            else result+=sum-10+'0';
        }
    }
    
    //加完小数部分以后要给result加一个小数点
    result+='.';
    
    //开始进行整数的运算,要看看算完小数后有没有进位
    //记录整数加法是否进位
    bool int_addExtra=false;

    for (int i=0; i<len_int; ++i) {
        if(float_addExtra==true && i==0){
            int n1=int_num1[i]-'0';
            int n2=int_num2[i]-'0';
            int sum=n1+n2+1;
            if(sum<10)result+=sum+'0';
            else{
                int_addExtra=true;
                result+=sum-10+'0';
            }
            continue;
        }
        if (int_addExtra==false) {
            int n1=int_num1[i]-'0';
            int n2=int_num2[i]-'0';
            int sum=n1+n2;
            if(sum<10)result+=sum+'0';
            else{
                int_addExtra=true;
                result+=sum-10+'0';
                if (i==len_int-1)result+='1';
            }
        }
        else {
            int n1=int_num1[i]-'0';
            int n2=int_num2[i]-'0';
            int sum=n1+n2+1;
            if(sum<10){
                int_addExtra=false;
                result+=sum+'0';
            }
            else{
                result+=sum-10+'0';
                if(i==len_int-1)result+='1';
            }
        }
        
    }
    //反转result
    reverse(result.begin(), result.end());
    return result;
}
int main(int argc, const char * argv[]) {
    string num1,num2;
    cin>>num1;
    cin>>num2;
    cout<<floatNumAdd(num1, num2);
    return 0;
}



发表于 2020-12-06 16:30:29 回复(0)
#include<iostream>
(720)#include<algorithm>
using namespace std;
string add(string a, string b){
	int len = a.length(), carry = 0;
	string c;
	for(int i = len - 1; i >= 0; i--){
		char temp = (carry + a[i] - '0' + b[i] - '0') / 10;
		c.push_back((carry + a[i] - '0' + b[i] - '0') % 10 + '0');
		carry = temp;
	}
	if(carry > 0) c.push_back('1');
	reverse(c.begin(), c.end());
	return c;
}
int main(){
	string a, b;
	while(cin >> a >> b){
		//分别取ab的整数部分ap, bp,小数部分aq, bq 
		string ap = string(a, 0, a.find("."));//将字符串a从下标0位置开始,数find(".")个 
		string aq = string(a, a.find(".") + 1, a.length() - a.find("."));
		string bp = string(b, 0, b.find("."));
		string bq = string(b, b.find(".") + 1, b.length() - b.find("."));
		//计算整数部分 先补零 
		if(ap.length() != bp.length()){
			int lenap = ap.length(), lenbp = bp.length();
			int lenp = max(lenap, lenbp);
			for(int i = 0; i < lenp - lenap; i++) ap = "0" + ap;
			for(int i = 0; i < lenp - lenbp; i++) bp = "0" + bp;
		}
		string sump = add(ap, bp);//整数部分结果 
		//计算小数部分 先补零 
		if(aq.length() != bq.length()){
			int lenaq = aq.length(), lenbq = bq.length();
			int lenq = max(lenaq, lenbq);
			for(int i = 0; i < lenq - lenaq; i++) aq = aq + "0";
			for(int i = 0; i < lenq - lenbq; i++) bq = bq + "0";
		}
		string sumq = add(aq, bq);//小数部分结果 
		//如果此时,小数部分有进位 
		if(sumq.length() > aq.length())
		{
		 sumq = sumq.substr(1);//若小数部分有进位,取从下标1开始的所有字符 
		 string ca = "1";
		 for(int i = 0; i < sump.length() - 1; i++) ca = "0" + ca;
		 sump = add(sump, ca);//把整数部分加上1 
		}
		cout << sump << "." << sumq << endl;
	}
	return 0;
} 

发表于 2020-05-02 11:16:10 回复(1)
#include<stdio.h>//1.根据小数点分割//2.小数部分相加//3.整数部分累加
int main()
{
    int i,j,diana,dianb; char a[100],b[100];
    int zhenga[100]={0},zhengb[100]={0},xiaoa[100]={0},xiaob[100]={0},zheng[100]={0},xiao[100]={0};
    scanf("%s%s",a,b);
    for(i=0;a[i]!='\0';i++) //1.找小数点的位置
        if(a[i]=='.')
        { diana=i;break;}
    for(i=0;b[i]!='\0';i++)
        if(b[i]=='.')
        { dianb=i;break;}
    for(i=diana+1;a[i]!='\0';i++)//2.小数部分
        xiaoa[i-(diana+1)]=a[i]-'0';//高位放在xiaoa[0]
    for(i=dianb+1;b[i]!='\0';i++)
        xiaob[i-(dianb+1)]=b[i]-'0';//高位放在xiaoa[0]
    int max=(strlen(a)-diana)>(strlen(b)-dianb)?(strlen(a)-diana):(strlen(b)-dianb);
    for(i=max-2;i>=0;i--)//小数累加
    {
        xiao[i]+=xiaoa[i]+xiaob[i];
        if(xiao[i]>9&&i!=0)
        {
            xiao[i-1]+=1;
            xiao[i]=xiao[i]%10;
        }
        if(xiao[i]>9&&i==0)
        {
            xiao[i]=xiao[i]%10;
            zheng[0]+=1;
        }
    }
    for(i=diana-1;i>=0;i--) //3.整数部分
        zhenga[diana-1-i]=a[i]-'0';//个位放在zhenga[0]
    for(i=dianb-1;i>=0;i--)
        zhengb[dianb-1-i]=b[i]-'0';//个位放在zhenga[0]
    for(i=0;i<(diana>dianb?diana:dianb);i++)//整数累加
    {
        zheng[i]+=zhenga[i]+zhengb[i];
        if(zheng[i]>9&&i!=(diana>dianb?diana:dianb)-1)//最后一位不用进位直接输出
        {//进位
            zheng[i]=zheng[i]%10;
            zheng[i+1]+=1;
        }
    }
    for(i=(diana>dianb?diana:dianb)-1;i>=0;i--) //整数倒序序输出
        printf("%d",zheng[i]);
    printf(".");
    for(i=0;i<max-1;i++) //小数正序输出
        printf("%d",xiao[i]);
}

发表于 2020-04-19 13:53:35 回复(0)
#include<bits/stdc++.h>
using namespace std;
int main() {
	string a,b;
	getline(cin,a);
	getline(cin,b);
	int i,j,al,ar,bl,br;
	for( i=0; i<a.length(); i++) {
		if(a[i]=='.') break;
	}
	for( j=0; j<b.length(); j++) {
		if(b[j]=='.') break;
	}
	al=i;
	bl=j;
	ar=a.length()-i-1;
	br=b.length()-j-1;
	while(al<bl) {
		a="0"+a;
		al++;
	}
	while(bl<al) {
		b="0"+b;
		bl++;
	}
	while(ar<br) {
		a=a+"0";
		ar++;
	}
	while(br<ar) {
		b=b+"0";
		br++;
	}
	char ans[100];
	int l=0,c=0,temp;
	for(int i=a.length()-1; i>=0; i--) {
		if(a[i]=='.') ans[l++]='.';
		else {
			temp=a[i]-'0'+b[i]-'0'+c;
			c=temp/10;
			ans[l++]=temp%10+'0';
		}
	}
	if(c!=0) ans[l++]=c;
	while(l>0) {
		printf("%c",ans[--l]);
	}
}

发表于 2020-03-22 17:34:49 回复(0)
#include<iostream>//定义结构体,从string中保存大数到数组中,其中整数位4位一逆序保存到dig1;小数位1位一顺序保存到dig2(因为小数位计算加法0.1+0.12=0.22,如果和整数位一样保存
#include<string>//和计算会出问题,比如会算成0.1+0.12=0.13;
#include<iomanip>
using namespace std;
struct M
{
    int dig1[1000];
    int dig2[4000];
    int size1;
    int size2;
    void init()
    {
        for (int i = 0; i < 1000; i++)
        {
            dig1[i] = dig2[i] = 0;
            size1 = size2 = 0;
        }
    }
    void set(string x)
    {
        init();
        int n = x.length();
        int len = x.find('.', 0);//偷懒用了string类的find函数找到'.'的下标,
        string y(x, len + 1, n);//然后从小数位开始到x的末位全部拷贝到新的y中
        int len1 = y.length();
        int i, j;
        int c = 1, temp = 0;
        for (i =0, j = 0; i<len1; i++)//直接从y[0]开始逐位保存到dig2[]中去
        {
            dig2[i] = y[i] - '0';
            size2++;
        }
        for (int i= len-1, j = 0; i >= 0; i--)
        {
            temp += (x[i] - '0') * c;
            c *= 10;
            j++;
            if (j == 4 || i == 0)
            {
                dig1[size1++] = temp;
                temp = 0; j = 0; c = 1;
            }
        }
    }
    void output()
    {
        for (int i = size1 - 1; i >= 0; i--)
        {
            if (i != size1 - 1)
                cout << setw(4) << setfill('0') << dig1[i];
            else
                cout << dig1[i];
        }
        cout << ".";
        for (int i = size2 - 1; i >= 0; i--)
        {
           
                cout << dig2[i];
        }
        cout << endl;
    }
    M operator+(M& s)//重载+
    {
        M ret;
        ret.init();
        int carry = 0, temp = 0;
       //nt len = size2 - s.size2;
       //f (len < 0)
        if (size2 > s.size2)//将两个保存小数的数组变成等长的数组如123和1234,将123变成1230,便于计算,因为一开始全部初始化了,所以size外的全部填为0了,所以不需要重新赋值
            s.size2 = size2;
        else
            size2 = s.size2;
       for(int i =size2-1; i>=0 ; i--)
        {
            temp = dig2[i] + s.dig2[i] + carry;//逢10进1
            carry = temp / 10;
            temp %= 10;
            ret.dig2[ret.size2++] = temp;
        }
        temp = 0;
        for (int i = 0; i < size1 || i < s.size1; i++)
        {
            temp = dig1[i] + s.dig1[i] + carry;//逢10000进1
            carry = temp / 10000;
            temp %= 10000;
            ret.dig1[ret.size1++] = temp;
        }
        if (carry != 0)
            ret.dig1[ret.size1++] = carry;
        return ret;
    }
}p,q,r;
string x1, x2;
int main()
{
    while (cin >> x1>>x2)
    {
        
        p.set(x1);
        q.set(x2);
        r = p + q;
        r.output();
    }
    return 0;
}

编辑于 2020-03-05 14:25:16 回复(1)

请问还有写的比我更麻烦的同学吗(sigh)

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

struct node{
    string num;
    int z_len;
    int x_len;
};

void get_len(node &a){
    int x_len, z_len = 0;
    for(int i = 0; i < a.num.length(); i++){
        if(a.num[i] != '.'){
            z_len++;
        }
        else
            break;
    }
    x_len = a.num.length() - z_len - 1;
    a.z_len = z_len;
    a.x_len = x_len;
}

void init(node &a, int max_z_len, int max_x_len){
    for(int i = 0; i < max_z_len - a.z_len; i++){
        a.num = "0" + a.num;
    }
    for(int i = 0; i < max_x_len - a.x_len; i++){
        a.num = a.num + "0";
    }
    a.z_len = max_z_len;
    a.x_len = max_x_len;
}

node my_add(node a, node b){
    node ret;
    get_len(a);
    get_len(b);
    int max_z_len = max(a.z_len, b.z_len);
    int max_x_len = max(a.x_len, b.x_len);
    init(a, max_z_len, max_x_len);
    init(b, max_z_len, max_x_len);
    string a_str = a.num;
    string b_str = b.num;
    string ret_str = "";
    int c = 0, temp;
    for(int i = a_str.length() - 1; i >= 0; i--){
        if(a_str[i] != '.'){
            temp = a_str[i] - '0' + b_str[i] - '0' + c;
            if(temp < 10){
                ret_str = (char)(temp + '0') + ret_str;
                c = 0;
            }
            else{
                ret_str = (char)(temp - 10 + '0') + ret_str;
                c = 1;
            }
        }
        else
            ret_str = "." + ret_str;
    }
    if(c == 1)
        ret_str = '1' + ret_str;
    ret.num = ret_str;
    get_len(ret);
    return ret;
}

int main(){
    string str1, str2;
    node nod1, nod2, ret;
    while(cin >> str1){
        cin >> str2;
        nod1.num = str1;
        nod2.num = str2;
        ret = my_add(nod1, nod2);
        cout << ret.num << endl;
    }
    return 0;
}
发表于 2019-03-20 16:17:26 回复(0)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int main()
{
    char a[1000];
    char b[1000];
    int qans[1000];
    int pans[1000];
    scanf("%s",a);
    getchar();
    scanf("%s",b);
    int alen=strlen(a);
    int blen=strlen(b);
    int apoint=0;
    int bpoint=0;//找到小数点存在的地方
    int i,j;
    for(i=0;i<alen;i++)
    {
        if(a[i]=='.')
            apoint=i;
    }
    for(i=0;i<blen;i++)
    {
        if(b[i]=='.')
            bpoint=i;
    }
    //对齐,补0
    if( apoint != bpoint )
    {
        int cut=(apoint>bpoint?(apoint - bpoint):(bpoint - apoint));
        if(apoint>bpoint)
        {
            //说明数组A前面的位数多!b数组需要移位和补0
            //cut有多大,就需要移位多少位!
            for(i=0;i<blen;i++)
            {
                b[blen-1-i+cut]=b[blen-1-i];
            }
            blen=blen+cut;
            bpoint=bpoint+cut;
            //然后前面的补0
            for(i=0;i<cut;i++)
            {
                b[i]='0';
            }
        }
        if(apoint<bpoint)
        {
            for(i=0;i<alen;i++)
            {
                a[alen-1-i+cut]=a[alen-1-i];
            }
            alen=alen+cut;
            apoint=apoint+cut;
            //然后前面的补0
            for(i=0;i<cut;i++)
            {
                a[i]='0';
            }
        }
    }
    //尾数补0!
    if(alen!=blen)
    {
        int cut=(alen>blen)?(alen-blen):(blen-alen);
        if(alen>blen)
        {
            //b的尾数需要补0
            for(i=0;i<cut;i++)
            {
                b[blen+i]='0';
            }
            blen=blen+cut;
        }
        else 
        {
            for(i=0;i<cut;i++)
            {
                a[alen+i]='0';
            }
            alen=alen+cut;
        }
    }
    //下面尾数开始相加了!
    int flag=0; //进位!
    for(i=alen-1;i>apoint;i--)
    {
        qans[i]=(a[i]-'0')+(b[i]-'0')+flag;
        if(qans[i]>=10)
        {
            flag=1;
            qans[i]=qans[i]-10;
        }
        else
        {
            flag=0;
        }
            
    }
    //下面整数部分开始相加!
    for(i=apoint-1;i>=0;i--)
    {
        pans[i]=(a[i]-'0')+(b[i]-'0')+flag;
        if(pans[i]>=10)
        {
            flag=1;
            pans[i]=pans[i]-10;
        }
        else
        {
            flag=0;
        }
    }
    //相加完毕!
    if(flag==1)
        printf("1");
 
    
        for(i=0;i<=apoint-1;i++)
        {
            printf("%d",pans[i]);
        }
        printf(".");
        for(i=apoint+1;i<alen;i++)
        {
            printf("%d",qans[i]);
        }
    
    return 0;
}

发表于 2018-09-09 09:54:38 回复(1)
#include <iostream>
#include <string>

using namespace std;

struct BigFloat{
    int intDigits[1000];
    int intlen;
    int decimalDigits[1000];
    int decimallen;
    BigFloat(string& a){
        fill(intDigits, intDigits+1000, 0);
        fill(decimalDigits, decimalDigits+1000, 0);
        int len = a.size();
        int pos = a.find('.');

        intlen = pos;
        for(int i=0; i<pos; i++){
            intDigits[i] = a[pos-i-1] - '0';
        }
        int idx = 0;
        for(int i=pos+1; i<len; i++){
            decimalDigits[idx++] = a[i] - '0';
        }
        decimallen = len - pos - 1;
    }

    void operator+(BigFloat b){
        decimallen = max(decimallen,b.decimallen);
        int carry = 0;
        //printf("%d %d\n",decimalDigits[0],b.decimalDigits[0]);
        for(int i=decimallen-1; i>=0; i--){
            int temp = decimalDigits[i] + b.decimalDigits[i] + carry;
            decimalDigits[i] = temp % 10;
            carry = temp / 10;
        }
        // 小数有进位的话会体现在carry上
        intlen = max(intlen,b.intlen);
        for(int i=0; i<intlen; i++){
            int temp = intDigits[i] + b.intDigits[i] + carry;
            intDigits[i] = temp % 10;
            carry = temp / 10;
        }
        if(carry > 0){
            intDigits[intlen++] = 1;
        }
        print();
    }

    void print(){
        while(intDigits[intlen-1] == 0) intlen--;
        while(decimalDigits[decimallen-1] == 0) decimallen--;
        if(intlen == 0) intlen = 1;
        for(int i=intlen-1; i>=0; i--){
            printf("%d",intDigits[i]);
        }
        printf(".");
        for(int i=0; i<decimallen; i++){
            printf("%d",decimalDigits[i]);
        }
        printf("\n");
    }

};
int main(){
    string s1,s2;
    cin >> s1 >> s2;
    BigFloat a(s1),b(s2);
    // a.print();
    // b.print();
    a + b;
    
    return 0;
}

发表于 2018-03-02 21:19:56 回复(0)

对齐就是使两浮点数字符串一样长,且小数点在相同的位置,如
4441976058474520796.650571
9057183.9521
对齐之后是:
4441976058474520796.650571
0000000000009057183.952100

#include <iostream>
using namespace std;

string add(string sa, string sb)
{
    string result, sc, sd;
/*************下面是将两浮点数对齐***********/
    int ia = sa.find(".", 0);
    int ib = sb.find(".", 0);
    sc = (ia>ib)?sa:sb;
    sd = (ia>ib)?sb:sa;
    int n = (ia>ib)?(ia-ib):(ib-ia);
    while(n--)
    {
        sd = "0"+sd;
    }
    int lenc = sc.length();
    int lend = sd.length();
    sa = (lenc>lend)?sc:sd;
    sb = (lenc>lend)?sd:sc;
    n = (lenc>lend)?(lenc-lend):(lend-lenc);
    while(n--)
    {
        sb+="0";
    }
/********下面是对对齐后的浮点数进行相加********/
    int carry = 0;
    for(int i = sa.length()-1; i>=0; i--)
    {
        if(sa[i]=='.')
        {
            result = "."+result;
            continue;
        }
        char value = sa[i]-'0'+sb[i]-'0'+carry;
        result = char(value%10+'0')+result;
        carry = value/10;
    }
    while(carry!=0)
    {
        result = char(carry%10+'0')+result;
        carry/=10;
    }
    return result;
}
int main()
{
    string sa, sb;
    while(cin>>sa)
    {
        cin>>sb;
        cout<<add(sa, sb)<<endl;
    }
    return 0;
}
编辑于 2018-03-01 21:02:38 回复(6)
#include<iostream>
#include<string>
/** \brief
整体来说,分为整数的相加和小数的相加,
整数部分分别存在z1和z2中,小数部分分别存在x1和x2中
剩下的就是字符串的相加了
 */


using namespace std;
int main(){
    string s1,s2,z1,z2,x1,x2;
    cin>>s1>>s2;
    z1=string(s1,0,s1.find(".",0));//取整数部分
    x1=string(s1,s1.find(".",0)+1,s1.length()-s1.find(".",0));//取小数部分
    z2=string(s2,0,s2.find(".",0));
    x2=string(s2,s2.find(".",0)+1,s2.length()-s2.find(".",0));
    //cout<<z1<<endl<<x1<<endl<<z2<<endl<<x2;
    if(z1.length()<z2.length())//总是使z1最长
        z1.swap(z2);
    if(x1.length()<x2.length())//总是使x1最长
        x1.swap(x2);
    int f=0;                    //标志位,进位时使用
    for(int i=x2.length()-1;i>=0;i--){  //先加小数部分,因为小数部分可能向整数部分进位
        int a=x1[i]-'0'+x2[i]-'0'+f;    //对应位相加,注意从最短数的最后一位相加
        x1[i]=a%10+'0';                 //更新该位值
        f=a/10;                         //更新进位标志
    }
    int l=z1.length()-1;                //整数部分相加
    for(int i=z2.length()-1;i>=0;i--){  //注意从最短数最后一位相加
        int a=z1[l]-'0'+z2[i]-'0'+f;
        z1[l]=a%10+'0';
        f=a/10;
        l--;                //调整最长位标志
    }
    while(l>=0){            //继续更新最长位,到起始值位置
        int a=z1[l]-'0'+f;
        z1[l]=a%10+'0';
        f=a/10;
        l--;
    }
    cout<<z1<<'.'<<x1;      //输出对应整数和小数
}

编辑于 2019-03-10 21:24:37 回复(3)
C++简洁代码
29行C++
#include<iostream>
using namespace std;
int main(){
	string f1,f2;
	while(getline(cin,f1)){
		getline(cin,f2);
		int pos1=f1.find('.');
		int pos2=f2.find('.');
		if(pos1>pos2){
			f2.insert(0,pos1-pos2,'0');
		}else{
			f1.insert(0,pos2-pos1,'0');
		}
		if(f1.length()>f2.length()){
			f2.insert(f2.length(),f1.length()-f2.length(),'0');
		} else{
			f1.insert(f1.length(),f2.length()-f1.length(),'0');
		}
		int a=0;
		for(int i=f1.length()-1;i>=0;--i){
			if(f1[i]=='.')	continue;
			f1[i]+=f2[i]-'0'+a;
			a=(f1[i]-'0')/10;
			f1[i]=(f1[i]-'0')%10+'0';
		}
		cout<<f1<<endl;
	} 
	return 0;
}


发表于 2020-03-02 11:32:16 回复(6)
这是不单独计算小数整数,而是一起计算的版本。方法为:使用-1代表小数点,注意为了能存储最高位的进位,数组要逆向存储,即a[0]为小数最后一位,在计算之前要把-1对齐,右移数组左边空出来的位置要置0。在大数计算时遇到-1跳到下一轮,计算结束后从右向左输出即可。
#include<iostream>
#include<string>
using namespace std;
int main(){
    string s1,s2;
    while(cin>>s1){
        cin>>s2;
        int a[110]={0},b[110]={0};
        int mida,midb,i;
        int n1=s1.length(),n2=s2.length(),n;
        for(i=0;i<n1;i++){
            if(s1[n1-i-1]=='.'){
                mida=i;
                a[i]=-1;
            }
            else
                a[i]=s1[n1-i-1]-'0';
        }
        for(i=0;i<n2;i++){
            if(s2[n2-i-1]=='.'){
                midb=i;
                b[i]=-1;
            }
            else
                b[i]=s2[n2-i-1]-'0';
        }
        if(mida<midb){
            int len=midb-mida;
            for(i=n1-1;i>=0;i--)
                a[i+len]=a[i];
            n1+=len;
            for(i=0;i<len;i++)
                a[i]=0;
        }
        else if(midb<mida){
            int len=mida-midb;
            for(i=n2-1;i>=0;i--)
                b[i+len]=b[i];
            n2+=len;
            for(i=0;i<len;i++)
                b[i]=0;
        }
        n=n1>n2?n1:n2;
        int k=0;
        for(i=0;i<n;i++){
            if(a[i]==-1) continue;
            int t=(a[i]+b[i]+k)/10;
            a[i]=(a[i]+b[i]+k)%10;
            k=t;
        }
        if(k!=0) a[n++]=k;
        for(i=n-1;i>=0;i--){
            if(a[i]==-1)
                cout<<".";
            else
                cout<<a[i];
        }
        cout<<endl;
    }
    return 0;
}

发表于 2018-01-18 14:15:58 回复(1)
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
int main(){
    string a, b; 
    while (cin >> a){
        cin >> b;
        int dota = a.find('.'), dotb = b.find('.');
        int lena = a.size() - dota, lenb = b.size() - dotb;
        int dis = lena - lenb;
        string tmp(abs(dis), '0');
        if (dis < 0){
            a += tmp;
        }
        else if (dis>0){
            b += tmp;
        }
        reverse(a.begin(), a.end());
        reverse(b.begin(), b.end());
        dis = dota - dotb;
        string tmp2(abs(dis), '0');
        if (dis < 0){
            a += tmp2;
        }
        else if (dis>0){
            b += tmp2;
        }
        string ans(a.size(), '.');
        int carry = 0;
        for (int i = 0; i < a.size(); i++){
            if (a[i] == '.') continue;
            ans[i] = (a[i] + b[i] + carry - '0'*2) % 10+'0';
            carry = (a[i] + b[i] + carry - '0'*2) / 10;
        }
        if (carry) ans += carry + '0';
        reverse(ans.begin(), ans.end());
        cout << ans << endl;
    }
}

发表于 2018-01-19 16:13:40 回复(0)
#include<stdio.h>
#include<string.h>
int main(){
    char str1[150],str2[150];
    while(gets(str1)){
        gets(str2);
        int len1=strlen(str1);
        int len2=strlen(str2);
        int apoint,bpoint;
        for(int i=0;i<len1;i++){
            if(str1[i]=='.'){
                apoint=i;
                break;
            }
        }
        for(int i=0;i<len2;i++){
            if(str2[i]=='.'){
                bpoint=i;
                break;
            }
        }
        if(apoint>bpoint){//                  str2后移整数补0
            int c=apoint-bpoint;
            for(int i=len2-1;i>=0;i--){
                str2[i+c]=str2[i];
            }
            for(int i=0;i<c;i++){
                str2[i]='0';
            }
            len2=len2+c;
            bpoint=apoint;
        }
        else{//                  str1后移整数补0
            int c=bpoint-apoint;
            for(int i=len1-1;i>=0;i--){
                str1[i+c]=str1[i];
            }
            for(int i=0;i<c;i++){
                str1[i]='0';
            }
            len1=len1+c;
            apoint=bpoint;
        }
        if(len1>len2){//                       str2小数补0
            for(int i=len2;i<len1;i++){
                str2[i]='0';
                len2=len1;
            }
        }
        else{//                       str1小数补0
            for(int i=len1;i<len2;i++){
                str1[i]='0';
                len1=len2;
            }
        }
        int a[150],b[150];//         b保存整数,a保存小数
        int idx1,idx2,carry1,carry2;
        idx1=idx2=carry1=carry2=0;
        for(int i=len1-1;i>apoint;i--){
            a[idx1++]=(str1[i]-'0'+str2[i]-'0'+carry1)%10;
            carry1=(str1[i]-'0'+str2[i]-'0'+carry1)/10;
        }
        carry2=carry1+carry2;
        for(int i=apoint-1;i>=0;i--){
            b[idx2++]=(str1[i]-'0'+str2[i]-'0'+carry2)%10;
            carry2=(str1[i]-'0'+str2[i]-'0'+carry2)/10;
        }
        if(carry2!=0){
            b[idx2++]=carry2;
        }
        //b[]从后往前输出,在输出小数点,从后往前输出a[]//
        for(int i=idx2-1;i>=0;i--){
            printf("%d",b[i]);
        }
        printf(".");
        for(int i=idx1-1;i>=0;i--){
            printf("%d",a[i]);
        }
        printf("\n");
    }
    return 0;
}

发表于 2019-02-14 12:04:23 回复(0)
#include<stdio.h>
#include<string.h>
int main()
{
    char A[101],B[101];
    int n,i,k,r,tmp;
    int mida,midb,lenA,lenB,lena,lenb,lenc,lend; /*mida,midb表示A和B中小数点的位置,其余分别是A,B,a,b,c,d的长度*/
    while(scanf("%d",&n)!=EOF)
    {
        for(r=0;r<n;r++)
        {
            int a[100]={0},b[100]={0},c[100]={0},d[100]={0};
            scanf(" %s %s",A,B);
            lenA=strlen(A);     /**计算A[]和B[]的长度*/
            lenB=strlen(B);
            i=0;
            while(A[i]!='.')    /**计算A[]中小数点的位置*/
                i++;
            mida=i;
            i=0;
            while(B[i]!='.')    /**计算B[]中小数点的位置*/
                i++;
            midb=i;
            lena=mida;  lenb=midb;      /**计算a[],b[],c[],d[]的长度*/
            lenc=lenA-mida-1; lend=lenB-midb-1;
            for(i=0;i<mida;i++) /**把A的整数部分赋给a[]*/
                a[i]=A[mida-1-i]-'0';
            for(i=0;i<midb;i++) /**把B的整数部分赋给b[]*/
                b[i]=B[midb-1-i]-'0';
            for(i=mida+1;i<lenA;i++)    /**把A的整小数部分赋给c[]*/
                c[i-1-mida]=A[i]-'0';
            for(i=midb+1;i<lenB;i++)    /**把B的小数部分赋给d[]*/
                d[i-1-midb]=B[i]-'0';
            k=0;
            for(i=(lenc>lend)?lenc:lend;i>=0;i--)   /**小数部分进行相加*/
            {
                tmp=c[i]+d[i]+k;
                c[i]=tmp%10;
                k=tmp/10;
            }
            for(i=0;i<lena||i<lenb;i++) /**整数部分进行相加*/
            {
                tmp=a[i]+b[i]+k;        /**这里的k是小数部分相加得到的进位,k=0或1*/
                a[i]=tmp%10;
                k=tmp/10;
            }
            if(k!=0)
                a[i++]=k;
            for(i--;i>=0;i--)           /**输出整数部分*/
            {
                printf("%d",a[i]);
            }
            printf(".");
            for(i=0;i<lenc||i<lend;i++)/**输出小数部分*/
                printf("%d",c[i]);
            printf("\n");
        }
    }
    return 0;
}
注意整数部分和小数部分加法不同,整数是把个位放在数组的0位置,然后从数组0位置开始相加
小数部分是把最高位放在0的位置,然后从数组尾部开始向0的位置相加
发表于 2017-03-07 21:15:16 回复(0)
#include<iostream>
using namespace std;
#include<string>
int main()
{
    string str1, str2;
    int pos1, pos2;
    int num1, num2;
    while (cin>>str1>>str2)
    {
        pos1 = str1.find('.', 0);
        pos2 = str2.find('.', 0);      
        num1 = str1.size() - pos1;
        num2 = str2.size() - pos2;
        if (pos1 < pos2)
            str1.insert(0, pos2 - pos1, '0');//前面补0
        else
            str2.insert(0, pos1 - pos2, '0');
        if (num1 < num2)
            str1.append(num2 - num1, '0');//后面补0
        else
            str2.append(num1 - num2, '0');
        int c = 0;//进位
        for (int i = str1.size() - 1; i >= 0; i--)
        {
            if (str1[i] == '.')
                i--;
            int add =((str1[i] - '0') + (str2[i] - '0') + c) % 10;
            c = ((str1[i] - '0') + (str2[i] - '0') + c) / 10;
            str1[i] = add + '0';
        }
        if(c != 0)
            str1.insert(0, 1, char(c));
        cout << str1 << endl;
    }
    return 0;
}

补0
编辑于 2020-04-20 09:36:33 回复(1)
这题简直了,有很多坑,我调了好久,终于全过了
#include <iostream>
using namespace std;

//实现string+1
void Add_1(string &s)
{
    bool add=false;
    for(int i=s.size()-1; i>=0; i--)
    {
        if(s[i]<'9')
        {
            add=true;
            s[i]=s[i]+1;
            for(int j=i+1; j<s.size(); j++)
                s[j]='0';
            break;
        }
    }
    if(!add)
    {
        for(int i=0; i<s.size(); i++)
            s[i]='0';
        s='1'+s;
    }
}

int main()
{
    string s1,s2;
    while(cin>>s1>>s2)
    {
        string z1,z2;
        string x1,x2;
        bool guo=false;
        for(int i=0; i<s1.size(); i++)
        {
            if(s1[i]=='.')
                guo=true;
            if(!guo) //整数部分
                z1=z1+s1[i];
            else//小数部分
                x1=x1+s1[i];
        }
        x1.erase(0,1);
        guo=false;
        for(int i=0; i<s2.size(); i++)
        {
            if(s2[i]=='.')
                guo=true;
            if(!guo) //整数部分
                z2=z2+s2[i];
            else//小数部分
                x2=x2+s2[i];
        }
        x2.erase(0,1);

        //整数部分
        //对齐
        int m=z2.size()-z1.size();
        if(m>0)
        {
            for(int i=1; i<=m; i++)
            {
                z1='0'+z1;
            }
        }
        m=z1.size()-z2.size();
        if(m>0)
        {
            for(int i=1; i<=m; i++)
            {
                z2='0'+z2;
            }
        }
        //进行计算
        string z="";
        bool jin=false;
        for(int i=z1.size()-1; i>=0; i--)
        {
            char t;
            if(jin)
                t=(z1[i]+z2[i]-'0'-'0'+1)%10+'0';
            else
                t=(z1[i]+z2[i]-'0'-'0')%10+'0';
            z=t+z;
            if(jin)
                jin=(z1[i]+z2[i]-'0'-'0'+1)>=10?true:false;
            else
                jin=(z1[i]+z2[i]-'0'-'0')>=10?true:false;
        }
        if(jin)
            z='1'+z;


        //小数部分
        //对齐
        if(x1.size()<x2.size())
        {
            for(int i=x1.size(); i<x2.size(); i++)
                x1=x1+'0';
        }
        else
        {
            for(int i=x2.size(); i<x1.size(); i++)
                x2=x2+'0';
        }
        //进行计算
        string x="";
        jin=false;
        for(int i=x1.size()-1; i>=0; i--)
        {
            char t;
            if(jin)
                t=(x1[i]+x2[i]-'0'-'0'+1)%10+'0';
            else
                t=(x1[i]+x2[i]-'0'-'0')%10+'0';
            x=t+x;
            if(jin)
                jin=(x1[i]+x2[i]-'0'-'0'+1)>=10?true:false;
            else
                jin=(x1[i]+x2[i]-'0'-'0')>=10?true:false;
        }
        if(jin)
            Add_1(z);
        cout<<z<<"."<<x<<endl;
    }
    return 0;
}

发表于 2024-02-24 15:45:24 回复(0)
#include <iostream>
#include <string>
#include<cmath>
using namespace std;
//double十进制下精度为15位,精度不够,将小数存在字符串中进行加法运算
void MakeStringEqualLength(string& a, string& b) {//整数部分和小数部分分别补零对齐
    int a_IntegerPartLength = a.find('.');//string.find()返回是索引下标(无符整数)
    int b_IntegerPartLength = b.find('.');
    int a_SignificandLength = a.length() - a.find('.') - 1;
    int b_SignificandLength = b.length() - b.find('.') - 1;
    int AddIntegerPartChar = abs(a_IntegerPartLength - b_IntegerPartLength);
    if (a_IntegerPartLength >= b_IntegerPartLength) {
        for (int i = 0; i < AddIntegerPartChar; ++i) {
            b.insert(0, 1, '0');//整数部分前插补零
        }
    }
    else {
        for (int i = 0; i < AddIntegerPartChar; ++i) {
            a.insert(0, 1, '0');
        }
    }
    int AddSignificandChar = abs(a_SignificandLength - b_SignificandLength);
    if (a_SignificandLength >= b_SignificandLength) {
        for (int i = 0; i < AddSignificandChar; ++i) {
            b += '0';//小数部分后插补零
        }
    }
    else {
        for (int i = 0; i < AddSignificandChar; ++i) {
            a += '0';
        }
    }
}

int main() {
    string a, b;
    cin >> a >> b;
    MakeStringEqualLength(a, b);
    string sum(a.length() + 1, '0');
    int carry = 0;
    for (int i = a.length(); i > 0; --i) {//从后往前逐位相加,carry保存进位信息
        if (a[i - 1] == '.') {//跳过小数点
            sum[i] = '.';
        }
        else {
            int digit = int(a[i - 1] - '0' + b[i - 1] - '0' + carry);
            sum[i] = digit % 10 + '0';
            carry = digit / 10;
        }
    }
    sum[0] = carry + '0';
    if (sum[0] == '0') {//结果的第一位单独处理,因为整数部分多预留了一位零,如果最终结果第一位为零则删去
        sum.erase(0, 1);
    }
    cout << sum;
    return 0;
}

编辑于 2024-02-12 14:47:39 回复(0)
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;

int main() {
    string num1, num2;
    while (getline(cin, num1)) {
        getline(cin, num2);
        int point_index1 = num1.find('.');  //第一个加数小数点位置
        int point_index2 = num2.find('.');  //第二个加数小数点位置
        //小数点对齐
        int point_index = max(point_index1, point_index2);
        for (int i = point_index1; i < point_index; i++) {
            num1.insert(0, "0");    //前面补0
        }
        for (int i = point_index2; i < point_index; i++) {
            num2.insert(0, "0");    //前面补0
        }
        //小数部分位数对齐
        int length = max(num1.length(), num2.length());
        while (num1.length() < length) {
            num1 += '0';    //后面补0
        }
        while (num2.length() < length) {
            num2 += '0';    //后面补0
        }
        num1.erase(point_index, 1); //去掉小数点
        num2.erase(point_index, 1); //去掉小数点
        int carry = 0;
        string result;  //运算结果(和)
        for (int i = length - 2; i >= 0; i--) {
            char digit = ((num1[i] - '0') + (num2[i] - '0') + carry) % 10 + '0';
            result = digit + result;
            carry = ((num1[i] - '0') + (num2[i] - '0') + carry) / 10;
        }
        result.insert(point_index, ".");    //补回小数点
        if (carry) {
            result.insert(0, "1");  //前面补进位
        }
        for (int i = result.size() - 1; i >= 0; i--) {
            if (result[i] == '0') {
                result = result.substr(0, result.size() - 1);   //删除尾部的0
            } else {
                break;
            }
        }
        cout << result << endl;
    }
    return 0;
}

编辑于 2024-02-04 23:13:14 回复(0)

问题信息

难度:
116条回答 9716浏览

热门推荐

通过挑战的用户

查看代码