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
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.
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;
}
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
You can convert a char to an int by subtracting '0' from it:
char sumdigit = (input1[0]-'0') + (input2[0]-'0') + '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();
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";
}
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;
}
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
Related
From this post: Compare two string as numeric value
I did not get a result.
Please open this post so that someone can answer my question.
I wrote this library (pr.h):
#include <iostream>
#include <string>
#include <bits/stdc++.h>
using namespace std;
class BigNum {
private:
string doSum(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;
}
bool isSmaller(string str1, string str2)
{
int n1 = str1.length(), n2 = str2.length();
if (n1 < n2)
return true;
if (n2 < n1)
return false;
for (int i = 0; i < n1; i++) {
if (str1[i] < str2[i])
return true;
else if (str1[i] > str2[i])
return false;
}
return false;
}
string findDiff(string str1, string str2)
{
if (isSmaller(str1, str2))
swap(str1, str2);
string str = "";
int n1 = str1.length(), n2 = str2.length();
int diff = n1 - n2;
int carry = 0;
for (int i = n2 - 1; i >= 0; i--) {
int sub = ((str1[i + diff] - '0') - (str2[i] - '0')
- carry);
if (sub < 0) {
sub = sub + 10;
carry = 1;
}
else
carry = 0;
str.push_back(sub + '0');
}
for (int i = n1 - n2 - 1; i >= 0; i--) {
if (str1[i] == '0' && carry) {
str.push_back('9');
continue;
}
int sub = ((str1[i] - '0') - carry);
if (i > 0 || sub > 0)
str.push_back(sub + '0');
carry = 0;
}
reverse(str.begin(), str.end());
return str;
}
public:
string num;
BigNum () {
num = "";
}
BigNum (string tmp) {
num = tmp;
}
string operator +(BigNum a1) {
return doSum(this->num,a1.num);
}
void operator = (BigNum * a1) {
this-> num = a1-> num;
}
void operator = (string tmp) {
this-> num = tmp;
}
bool operator > (BigNum a1) {
if (this->num>a1.num){
return true;
}
else{
return false;
}
}
bool operator < (BigNum a1) {
if (this->num<a1.num){
return true;
}
else{
return false;
}
}
string operator - (BigNum a1) {
return findDiff(this->num, a1.num);
}
friend ostream &operator<<( ostream &output, const BigNum &D ) {
output << D.num;
return output;
}
friend istream &operator>>( istream &input, BigNum &D ) {
input >> D.num;
return input;
}
string operator -=(string tmp){
this->num=findDiff(this->num, tmp);
return this->num;
}
};
And this code:
// C++ program for implementation of Bubble sort
#include "pr.h"
#include <bits/stdc++.h>
using namespace std;
void swap(BigNum *xp, BigNum *yp)
{
BigNum temp = *xp;
*xp = *yp;
*yp = temp;
}
// A function to implement bubble sort
void bubbleSort(BigNum arr[], int n)
{
int i, j;
for (i = 0; i < n-1; i++)
// Last i elements are already in place
for (j = 0; j < n-i-1; j++)
if (arr[j] > arr[j+1])
swap(&arr[j], &arr[j+1]);
}
/* Function to print an array */
void printArray(BigNum arr[], int size)
{
int i;
for (i = 0; i < size; i++)
cout << arr[i] << " ";
cout << endl;
}
// Driver code
int main()
{
BigNum arr[5];
arr[0]="5";
arr[1]="5";
arr[2]="1";
arr[3]="3";
arr[4]="8";
int n = sizeof(arr)/sizeof(arr[0]);
bubbleSort(arr, n);
cout<<"Sorted array: \n";
printArray(arr, n);
return 0;
}
My problem is that this program can only sort 1-digit numbers and gives errors for multi-digit numbers
Example:
This code:
BigNum arr [5];
arr [0] = "100";
arr [1] = "5";
arr [2] = "1";
arr [3] = "3";
arr [4] = "8";
int n = sizeof (arr) / sizeof (arr [0]);
bubbleSort (arr, n);
cout << "Sorted array: \ n";
printArray (arr, n);
Prints this value:
1 100 3 5 8
bool operator < (BigNum a1) is calling std::string:: operator<, thus you getting lexicographical order. The operators < and > should call isSmaller.
bool operator > (const BigNum& a1) const {
return !isSmaller(a1) && num != a1.num;
}
bool operator < (const BigNum& a1) const {
return isSmaller(a1);
}
Do not use constructions
if (smth) return true else return false. You already get true or false in smth, use return smth.
I have written a P function that removes c digits in an n integer number.
The head of the function is : void P(int &n, int &c).
Let's say n = 23734 and c = 3
The output should be: 274
This what i have tried before asking here.
void P(int &n,int &c)
{
int p=1,k=0;
while(n)
{
if(n%10==c)
n=n/10;
else
{
k=k+n%10*10;
n=n/10;
}
}
cout<<k;
}
P.S. I am new here that's why i don't know how to correctly add codes.
Use std::to_string() to convert your n to a string:
std::string s = std::to_string(n);
then convert c to a char by adding 48 to it which is the equivalent of ‘0’ + your number c = some char between ‘0’ and ‘9’.
char myChar = '0' + c;
Now erase every occurrence of myChar by looping through the string and removing the index where myChar == s[i]
for(int i = 0; i < s.size(); i ++){
If(myChar == s[i]){
s.erase(s.begin()+i);
i--;
}
}
Finally, convert the string back to an int:
n = std::stoi (s);
Edit: you can accomplish this with division and modulo operations as well, as mentioned in one of the comments.
Here's an example I just put together:
bool sign = false; // false -> + , true -> -
if (n < 0) { n = -n; sign = true; }
int back = 0;
int front = n;
int i = 0;
while (front > 0) {
if(front % 10 != c){
back += (front % 10) * std::pow(10, i++);
}
front /= 10;
}
n = sign ? -back : back;
I need to create a generic function that changes from any starting base, to any final base. I have everything down, except my original function took (and takes) an int value for the number that it converts to another base. I decided to just overload the function. I am Ok with changing between every base, but am slightly off when using my new function to take in a string hex value.
The code below should output 1235 for both functions. It does for the first one, but for the second, I am currently getting 1347. Decimal to Hex works fine - It's just the overloaded function (Hex to anything else) that is slightly off.
Thanks.
#include <iostream>
#include <stack>
#include <string>
#include <cmath>
using namespace std;
void switchBasesFunction(stack<int> & myStack, int startBase, int finalBase, int num);
void switchBasesFunction(stack<int> & myStack, int startBase, int finalBase, string s);
int main()
{
stack<int> myStack;
string hexNum = "4D3";
switchBasesFunction(myStack, 8, 10, 2323);
cout << endl << endl;
switchBasesFunction(myStack, 16, 10, hexNum);
return 0;
}
void switchBasesFunction(stack<int> & myStack, int startBase, int finalBase, int num)
{
int totalVal = 0;
string s = to_string(num);
for (int i = 0; i < s.length(); i++)
{
myStack.push(s.at(i) - '0');
}
int k = 0;
while (myStack.size() > 0)
{
totalVal += (myStack.top() * pow(startBase, k++));
myStack.pop();
}
string s1;
while (totalVal > 0)
{
int temp = totalVal % finalBase;
totalVal = totalVal / finalBase;
char c;
if (temp < 10)
{
c = temp + '0';
s1 += c;
}
else
{
c = temp - 10 + 'A';
s1 += c;
}
}
for (int i = s1.length() - 1; i >= 0; i--)
{
cout << s1[i];
}
cout << endl << endl;
}
void switchBasesFunction(stack<int> & myStack, int startBase, int finalBase, string s)
{
int totalVal = 0;
for (int i = 0; i < s.length(); i++)
{
myStack.push(s.at(i) - '0');
}
int k = 0;
while (myStack.size() > 0)
{
totalVal += (myStack.top() * pow(startBase, k++));
myStack.pop();
}
string s1;
while (totalVal > 0)
{
int temp = totalVal % finalBase;
totalVal = totalVal / finalBase;
char c;
if (temp < 10)
{
c = temp + '0';
s1 += c;
}
else
{
c = temp - 10 + 'A';
s1 += c;
}
}
for (int i = s1.length() - 1; i >= 0; i--)
{
cout << s1[i];
}
cout << endl << endl;
}
Sorry, but I'm having issues understanding your code, so I thought I'd simplify it.
Here's the algorithm / code (untested):
void convert_to_base(const std::string& original_value,
unsigned int original_base,
std::string& final_value_str,
unsigned int final_base)
{
static const std::string digit_str =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if ((original_base > digit_str.length()) || (final_base > digit_str.length())
{
std::cerr << "Base value exceeds limit of " << digit_str.length() << ".\n";
return;
}
// Parse string from right to left, smallest value to largest.
// Convert to decimal.
unsigned int original_number = 0;
unsigned int digit_value = 0;
int index = 0;
for (index = original_value.length(); index > 0; --index)
{
std::string::size_type posn = digit_str.find(original_value[index];
if (posn == std::string::npos)
{
cerr << "unsupported digit encountered: " << original_value[index] << ".\n";
return;
}
digit_value = posn;
original_number = original_number * original_base + digit_value;
}
// Convert to a string of digits in the final base.
while (original_number != 0)
{
digit_value = original_number % final_base;
final_value_str.insert(0, 1, digit_str[digit_value]);
original_number = original_number / final_base;
}
}
*Warning: code not tested via compiler.**
I am having some issues trying to get my code to work. It prints ALMOST the right data but maybe it isn't looping correctly? I don't think it repeats the key through the alphabet. It's all lowercase and doesn't exceed 26.
void vigenereEncrypt( const char plaintext[], char ciphertext[], const char key[] )
{
int idx;
int j;
for( idx = 0, j = 0; idx <= strlen(plaintext); idx++ )
{
if ( CHAR_OUT_OF_RANGE(plaintext[idx]) )
{
ciphertext[idx] = plaintext[idx];
}
else
{
ciphertext[idx] = plaintext[idx];
ciphertext[idx] += key[j] - MIN_ASCII_VALUE;
if (ciphertext[idx] >= MAX_ASCII_VALUE) ciphertext[idx] += -MAX_ASCII_VALUE + MIN_ASCII_VALUE - 1;
}
j = (j + 1) % strlen(key);
}
ciphertext[idx] = 0;
}
for instance: if I enter the plaintext toner with a key of jerry the output will be csevé. It should change it to csevp
Do everybody (especially yourself) a favor, and use std::string instead of C-style strings. Then use a standard algorithm instead of writing messing up the loops on your own.
#include <iostream>
#include <iterator>
#include <algorithm>
class crypt {
std::string key;
size_t pos;
public:
crypt(std::string const &k) : key(k), pos(0) { }
char operator()(char input) {
char ret = input ^ key[pos];
pos = (pos + 1) % key.size();
return ret;
}
};
int main() {
std::string input("This is some input to be encrypted by the crappy encryption algorithm.");
std::transform(input.begin(), input.end(),
std::ostream_iterator<char>(std::cout),
crypt("This is the key"));
return 0;
}
Your loop is going one-to-far. You should use < instead of <=. And I assume you should be testing for > MAX_ASCII_VALUE, not >= (but you haven't shown what MAX_ASCII_VALUE is).
But your basic problem is a signed vs. unsigned char problem. With signed chars, when it goes above 127 it wraps around and becomes negative, so the > test will fail when it should have passed.
void vigenereEncrypt(const char plaintext[], char ciphertext[], const char key[])
{
size_t i, j;
for(i = 0, j = 0; i < strlen(plaintext); ++i )
{
ciphertext[i] = plaintext[i];
if (!CHAR_OUT_OF_RANGE(plaintext[i]))
{
ciphertext[i] += (uchar)key[j] - (uchar)MIN_ASCII_VALUE;
if ((uchar)ciphertext[i] > (uchar)MAX_ASCII_VALUE)
ciphertext[i] -= (uchar)MAX_ASCII_VALUE - (uchar)MIN_ASCII_VALUE + 1;
}
j = (j + 1) % strlen(key);
}
ciphertext[i] = 0;
}
I am preparing the interview questions not for homework. There is one question about how to multiple very very long integer. Could anybody offer any source code in C++ to learn from? I am trying to reduce the gap between myself and others by learning other's solution to improve myself.
Thanks so much!
Sorry if you think this is not the right place to ask such questions.
you can use GNU Multiple Precision Arithmetic Library for C++.
If you just want an easy way to multiply huge numbers( Integers ), here you are:
#include<iostream>
#include<string>
#include<sstream>
#define SIZE 700
using namespace std;
class Bignum{
int no[SIZE];
public:
Bignum operator *(Bignum& x){ // overload the * operator
/*
34 x 46
-------
204 // these values are stored in the
136 // two dimensional array mat[][];
-------
1564 // this the value stored in "Bignum ret"
*/
Bignum ret;
int carry=0;
int mat[2*SIZE+1][2*SIZE]={0};
for(int i=SIZE-1;i>=0;i--){
for(int j=SIZE-1;j>=0;j--){
carry += no[i]*x.no[j];
if(carry < 10){
mat[i][j-(SIZE-1-i)]=carry;
carry=0;
}
else{
mat[i][j-(SIZE-1-i)]=carry%10;
carry=carry/10;
}
}
}
for(int i=1;i<SIZE+1;i++){
for(int j=SIZE-1;j>=0;j--){
carry += mat[i][j]+mat[i-1][j];
if(carry < 10){
mat[i][j]=carry;
carry=0;
}
else{
mat[i][j]=carry%10;
carry=carry/10;
}
}
}
for(int i=0;i<SIZE;i++)
ret.no[i]=mat[SIZE][i];
return ret;
}
Bignum (){
for(int i=0;i<SIZE;i++)
no[i]=0;
}
Bignum (string _no){
for(int i=0;i<SIZE;i++)
no[i]=0;
int index=SIZE-1;
for(int i=_no.length()-1;i>=0;i--,index--){
no[index]=_no[i]-'0';
}
}
void print(){
int start=0;
for(int i=0;i<SIZE;i++)
if(no[i]!=0){
start=i;
break; // find the first non zero digit. store the index in start.
}
for(int i=start;i<SIZE;i++) // print the number starting from start till the end of array.
cout<<no[i];
cout<<endl;
return;
}
};
int main(){
Bignum n1("100122354123451234516326245372363523632123458913760187501287519875019671647109857108740138475018937460298374610938765410938457109384571039846");
Bignum n2("92759375839475239085472390845783940752398636109570251809571085701287505712857018570198713984570329867103986475103984765109384675109386713984751098570932847510938247510398475130984571093846571394675137846510874510847513049875610384750183274501978365109387460374651873496710394867103984761098347609138746297561762234873519257610");
Bignum n3 = n1*n2;
n3.print();
return 0;
}
as you can see, it's multiply 2 huge integer :) ... (up to 700 digits)
Try this:
//------------DEVELOPED BY:Ighit F4YSAL-------------
#include<iostream>
#include<string>
#include<sstream>
#define BIG 250 //MAX length input
using namespace std;
int main(){
int DUC[BIG][BIG*2+1]={0},n0[BIG],n1[BIG],i,t,h,carry=0,res;
string _n0,_n1;
while(1){
//-----------------------------------get data------------------------------------------
cout<<"n0=";
cin>>_n0;
cout<<"n1=";
cin>>_n1;
//--------------------string to int[]----------------------------------------
for(i=_n0.length()-1,t=0;i>=0,t<=_n0.length()-1;i--,t++){
n0[i]=_n0[t]-'0';
}
i=0;
for(i=_n1.length()-1,t=0;i>=0,t<=_n1.length()-1;i--,t++){
n1[i]=_n1[t]-'0';
}
i=0;t=0;
//--------------------------produce lines of multiplication----------------
for(i=0;i<=_n1.length()-1;i++){
for(t=0;t<=_n0.length()-1;t++){
res=((n1[i]*n0[t])+carry);
carry=(res/10);
DUC[i][t+i]=res%10;
}
DUC[i][t+i]=carry;
carry=0;
}
i=0;t=0;res=0;carry=0;
//-----------------------------add the lines-------------------------------
for(i=0;i<=_n0.length()*2-1;i++){
for(t=0;t<=_n1.length()-1;t++){
DUC[BIG-1][i]+=DUC[t][i];
//cout<<DUC[t][i]<<"-";
}
res=((DUC[BIG-1][i])+carry);
carry=res/10;
DUC[BIG-1][i]=res%10;
//cout<<" ="<<DUC[BIG-1][i]<<endl;
}
i=0;t=0;
//------------------------print the result------------------------------------
cout<<"n1*n0=";
for(i=_n0.length()*2-1;i>=0;i--){
if((DUC[BIG-1][i]==0) and (t==0)){}else{cout<<DUC[BIG-1][i];t++;}
//cout<<DUC[BIG-1][i];
}
//-------------------------clear all-------------------------------------
for(i=0;i<=BIG-1;i++){
for(t=0;t<=BIG*2;t++){
DUC[i][t]=0;
}
n0[i]=0;n1[i]=0;
}
//--------------------------do it again-------------------------------------
cout<<"\n------------------------------------------------\n\n";
}
return 0;
}
This solution is good for very very big numbers but not so effective for factorial calculation of very big numbers. Hope it will help someone.
#include <iostream>
#include <string>
using namespace std;
string addition(string a, string b) {
string ans = "";
int i, j, temp = 0;
i = a.length() - 1;
j = b.length() - 1;
while (i >= 0 || j >= 0) {
if (i >= 0 && a[i])
temp += a[i] - '0';
if (j >= 0 && b[j])
temp += b[j] - '0';
int t = (temp % 10);
char c = t + '0';
ans = ans + c;
temp = temp / 10;
i--;
j--;
}
while (temp > 0) {
int t = (temp % 10);
char c = t + '0';
ans = ans + c;
temp = temp / 10;
}
string fnal = "";
for (int i = ans.length() - 1;i >= 0;i--) {
fnal = fnal + ans[i];
}
return fnal;
}
string multiplication(string a, string b) {
string a1, b1 = "0";
int i, j, temp = 0, zero = 0;
i = a.length() - 1;
int m1, m2;
while (i >= 0) {
a1 = "";
m1 = a[i] - '0';
j = b.length() - 1;
while (j >= 0) {
m2 = b[j] - '0';
temp = temp + m1*m2;
int t = temp % 10;
char c = t + '0';
a1 = a1 + c;
temp = temp / 10;
j--;
}
while (temp > 0) {
int t = (temp % 10);
char c = t + '0';
a1 = a1 + c;
temp = temp / 10;
}
string fnal = "";
// reverse string
for (int i = a1.length() - 1;i >= 0;i--) {
fnal = fnal + a1[i];
}
a1 = fnal;
//add zero
for (int p = 0;p < zero;p++)
a1 = a1 + '0';
b1 = addition(a1, b1);
i--;
zero++;
}
return b1;
}
// upto 50 is ok
int factorial(int n) {
string a = "1";
for (int i = 2;i <= n;i++) {
string b = to_string(i);
a = multiplication(a, b);
}
cout << a << endl;
return a.length();
}
int main() {
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
int n;
cin >> n;
//cout << factorial(n) << endl;
string a, b;
a = "1281264836465376528195645386412541764536452813416724654125432754276451246124362456354236454857858653";
b = "3767523857619651386274519192362375426426534237624548235729562582916259723586347852943763548355248625";
//addition(a, b);
cout << multiplication(a, b);
return 0;
}