4

i was looking around the forums and i still couldnt find my answer to my problem. I got two strings, that are just really an array of numbers. for example(i just choose random numbers

 string input1="12345678909876543212"; string input2="12345"; 

I want to add these two string together but act them like there integers. My goal is creating a class where i can add bigger numbers than (long long int) so it can exceed the largest long long int variable.

So i revese the string with no problem, so now there

 input1="21234567890987654321" input2="54321" 

then i tried adding, let's say input1[0]+input2[0] (2+5) to a new string lets call it newString[0] where that would equal (7); but i cant find a good way to temporally convert the current number in the string so i can add it to the new string? can anyone help. I get sick and tired of atoi,stof,stod. they don't seem to work at all for me. Any way i can make this function work. I don't care about making the class yet, i just care about finding a way to add those two strings mathematically but still maintaining the newString's string format. Thank you for whoever can figure this out for me

2
  • Use an existing bignum library, for example: boost multiprecision. See this wikipedia article for a general discussion: en.wikipedia.org/wiki/Arbitrary-precision_arithmetic Commented Oct 9, 2013 at 2:56
  • well i want to create my own thats the thing Commented Oct 9, 2013 at 3:04

8 Answers 8

5

Okay, so, assuming your only problem is with the logic, not the class design thing, I came up with this logic

  • fill up the inputs with 0s, checking the lengths, match the lengths
  • add like normal addition, keeping track of carry
  • finally remove leading zeros from result

So using std::transform with a lambda function on reverse iterators :-

char carry = 0; std::transform(input1.rbegin(),input1.rend(),input2.rbegin(), result.rbegin(),[&carry]( char x, char y){ char z = (x-'0')+(y-'0') + carry; if (z > 9) { carry = 1; z -= 10; } else { carry = 0; } return z + '0'; }); //And finally the last carry result[0] = carry + '0'; //Remove the leading zero n = result.find_first_not_of("0"); if (n != string::npos) { result = result.substr(n); } 

See Here

Edit "Can you comment on what your doing here"

 +--------+--------------+------------+-------> Reverse Iterator | | | | std::transform( | input1.rbegin(), input1.rend(),input2.rbegin(), result.rbegin(), [&carry]( char x, char y){ //This starts a lambda function char z = (x-'0')+(y-'0') + carry; // x,y have ASCII value of each digit // Substracr ASCII of 0 i.e. 48 to get the "original" number // Add them up if (z > 9) //If result greater than 9, you have a carry { carry = 1; // store carry for proceeding sums z -= 10; // Obviously } else { carry = 0; //Else no carry was generated } return z + '0'; // Now you have "correct" number, make it a char, add 48 }); 

std::transform is present in header <algorithm>, see the ideone posted link.

Sign up to request clarification or add additional context in comments.

3 Comments

Can you comment on what your doing here... I'm not sure what's going on all the way? Thank you
And std::transform? I can't seem to find it.. I'm using visual studio
@Juan updated answer, if you still don't get it, I suggest you to get a good book
3

Here's A Solution for adding two numbers represented as strings .

#include<iostream> using namespace std; string add(string a, string b) { int al=a.size()-1; int bl=b.size()-1; int carry=0; string result=""; while(al>=0 && bl>=0) { int temp = (int)(a[al] - '0') + (int)(b[bl] - '0') + carry ; carry = 0; if(temp > 9 ) { carry=1; temp=temp-10; } result+=char(temp + '0'); al--; bl--; } while(al>=0) { int temp = (int)(a[al] - '0') + carry ; carry = 0; if(temp>9) { carry=1; temp=temp%10; } result+=char(temp + '0'); al--; } while(bl>=0) { int temp = (int)(b[bl] - '0') + carry ; carry = 0; if(temp>9) { carry=1; temp=temp%10; } result+=char(temp + '0'); bl--; } if(carry) result+="1"; string addition=""; for(int i=result.size()-1;i>=0;i--) addition+=result[i]; // reversing the answer return addition; } string trim(string a) // for removing leading 0s { string res=""; int i=0; while(a[i]=='0') i++; for(;i<a.size();i++) res+=a[i]; return res; } int main() { string a; string b; cin>>a>>b; cout<<trim(add(a,b))<<endl; } 

1 Comment

A small bug in the code. After adding carry to the "temp" set carry = 0 (in the three loop) as the carry I already added to the resulting added number.
0

I am not a very femilier with C++ but cant we do this?

 int i = stoi( input1[0]); int j = stoi( input2[0]); int x = i+j; 

Please note this can be done in C++11 Please refer [1] and 2 as well

3 Comments

the compliler complains about that. I honestly don't know what.
Are you using C++11? can you please try this as well std::string s = "21234567890987654321"; int i = std::stoi(s);
for(i=0; 0<= 20; i++) { int x,y; x=std::stoi(input1[i]); }
0

You can convert a char to an int by subtracting '0' from it:

char sumdigit = (input1[0]-'0') + (input2[0]-'0') + '0'; 

Comments

0

atoi() would be a better to go, as far as converting input[0] to an int:

int temp = atoi(input.substr(0,1).c_str()); 

then use stringstream to convert back to string:

stringstream convert; convert << temp; string newString = convert.str(); 

Comments

0

Here is a solution, but this is so far from sensible that it is not even funny.

GCC 4.7.3: g++ -Wall -Wextra -std=c++0x dumb-big-num.cpp

#include <algorithm> #include <cctype> #include <iostream> #include <sstream> #include <stdexcept> #include <string> // dumb big num // unsigned integer class DBN { public: DBN() : num("0") {} explicit DBN(const std::string& s) : num(s) { for (const auto& c : num) { if (!std::isdigit(c)) { throw std::invalid_argument("DBN::DBN"); } } std::reverse(std::begin(num), std::end(num)); } DBN operator+(const DBN& rhs) const { DBN tmp(*this); return tmp += rhs; } DBN& operator+=(const DBN& rhs) { std::string r; const int m = std::min(num.size(), rhs.num.size()); int c = 0; for (int i = 0; i < m; ++i) { int s = (num[i] - '0') + (rhs.num[i] - '0') + c; c = s / 10; s %= 10; r += static_cast<char>('0' + s); } const std::string& ref = num.size() < rhs.num.size() ? rhs.num : num; for (int i = m; i < ref.size(); ++i) { int s = (ref[i] - '0') + c; c = s / 10; s %= 10; r += static_cast<char>('0' + s); } if (0 < c) { r += '1'; } num = r; return *this; } friend std::ostream& operator<<(std::ostream& os, const DBN& rhs); friend std::istream& operator>>(std::istream& os, DBN& rhs); private: std::string num; }; std::ostream& operator<<(std::ostream& os, const DBN& rhs) { std::string s(rhs.num); std::reverse(std::begin(s), std::end(s)); return os << s; } std::istream& operator>>(std::istream& is, DBN& rhs) { std::stringstream ss; char c; while (is && std::isspace(is.peek())) { is.ignore(); } while (is) { if (!std::isdigit(is.peek())) { break; } is >> c; ss << c; } DBN n(ss.str()); rhs = n; return is; } int main() { DBN a, b, t; while (std::cin >> a >> b) { std::cout << a + b << "\n"; (t += a) += b; } std::cout << t << "\n"; } 

Comments

0

Here it is a simple C++ code

string Sum(string a, string b) { if(a.size() < b.size()) swap(a, b); int j = a.size()-1; for(int i=b.size()-1; i>=0; i--, j--) a[j]+=(b[i]-'0'); for(int i=a.size()-1; i>0; i--) if(a[i] > '9') { int d = a[i]-'0'; a[i-1] = ((a[i-1]-'0') + d/10) + '0'; a[i] = (d%10)+'0'; } if(a[0] > '9') { string k; k+=a[0]; a[0] = ((a[0]-'0')%10)+'0'; k[0] = ((k[0]-'0')/10)+'0'; a = k+a; } return a; } 

Comments

0

cited from C - Adding the numbers in 2 strings together if a different length answer, I write a more readable code:

void str_reverse(char *beg, char *end){ if(!beg || !end)return; char cTmp; while(beg < end){ cTmp = *beg; *beg++ = *end; *end-- = cTmp; } } #define c2d(c) (c - '0') #define d2c(d) (d + '0') void str_add(const char* s1, const char* s2, char* s_ret){ int s1_len = strlen(s1); int s2_len = strlen(s2); int max_len = s1_len; int min_len = s2_len; const char *ps_max = s1; const char *ps_min = s2; if(s2_len > s1_len){ ps_min = s1;min_len = s1_len; ps_max = s2;max_len = s2_len; } int carry = 0; int i, j = 0; for (i = max_len - 1; i >= 0; --i) { // this wrong-prone int idx = (i - max_len + min_len) >=0 ? (i - max_len + min_len) : -1; int sum = c2d(ps_max[i]) + (idx >=0 ? c2d(ps_min[idx]) : 0) + carry; carry = sum / 10; sum = sum % 10; s_ret[j++] = d2c(sum); } if(carry)s_ret[j] = '1'; str_reverse(s_ret, s_ret + strlen(s_ret) - 1); } 

test code as below:

void test_str_str_add(){ char s1[] = "123"; char s2[] = "456"; char s3[10] = {'\0'}; str_add(s1, s2, s3); std::cout<<s3<<std::endl; char s4[] = "456789"; char s5[10] = {'\0'}; str_add(s1, s4, s5); std::cout<<s5<<std::endl; char s7[] = "99999"; char s8[] = "21"; char s9[10] = {'\0'}; str_add(s7, s8, s9); std::cout<<s9<<std::endl; } 

output:

579

456912

100020

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.