Fast Multiplication on SPOJ - c++

I am solving FAST MULTIPLICATION on SPOJ.
My solution looks like this:
#include<bits/stdc++.h>
using namespace std;
int max(int a,int b)
{
if(a>b) return a;
return b;
}
long karatsuba_multiply(int x,int y)
{
if(x<10 or y<10) return x*y;
int n=max(to_string(x).length(),to_string(y).length());
int m=(int)ceil(n/2.0);
long p=(long)pow(10,m);
long a=(long)(floor(x/p));
long b=x%p;
long c=(long)(y/p);
long d=y%p;
long ac=karatsuba_multiply(a,c);
long bd=karatsuba_multiply(b,d);
long adbc=karatsuba_multiply(a+b,c+d)-ac-bd;
return (long)(pow(10*1,2*m)*ac+pow(10*1,m)*adbc+bd);
}
int main()
{
int a,b,t;
cin>>t;
while(t--)
{
cin>>a>>b;
cout<<karatsuba_multiply(a,b)<<endl;
}
return 0;
}
This code is giving correct output on coding blocks IDE as well as other IDEs. But this solution is being marked wrong on SPOJ. Can anyone tell me what I am doing wrong?

C++ originally only supports the maximum length of unsigned long long integers as about 1.8e19.
According to the problem, the answer can shoot up to 1e100000000 which is far larger.
Ways to solve this are:
Use Strings to store integers and use the operations on strings to multiply. You can check this article
Use C++ boost library. This library supports integer operations beyond 1e19 limit.
Another method would be to use some other language which supports greater than 64-bit integer like Python or use BigInteger Class in Java

From the problem description:
Input
n [the number of multiplications <= 1000]
l1 l2 [numbers to multiply (at most 10000 decimal digits each)]
Text grouped in [ ] does not appear in the input file.
A number with 10000 decimal digits is too large to fit in an int for typical sizes of int. You need to use a differnt type for the input and to carry out the multiplication. There is no built in type that can store integers that large.

Related

Overflow in long long int

I am facing an overflow problem for this case and getting output as 7392445620511834112 , I wanted to multiply 2 large values of b and c and want to store that value.
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
int main()
{
ll b=1000000000000000000;
ll c=2000000000000000000;
ll out=b*c;
cout<<out;
}
If you change from long long to unsigned long long you could get a little closer. If you don't care about absolute precision you could use a floating point type instead here even just float is enough to store the output in a way that cout displays it correctly but with bigger or less round numbers or when processing the output in other ways you may want to use double or long double for more size and precision.
And don't listen to all the people telling you you are doing it wrong they spend all their day arguing about those kind of things on stack exchange. How you are doing it is perfectly fine otherwise it would not compile.

Calculation the sum of long long int

(calculating the sum of long long numbers)
whenever I input a long long number the program returns always -1 or -2 anyone knows why?
#include <iostream>
#include <math.h>
#include <string>
#include<iomanip>
using namespace std;
int main()
{
int n,i;
long long x1,x2,s;
do{
cin>>n;
}while(n<1);
long long t1[n];
long long t2[n];
string ch1,ch2;
i=0;
do{
do{
scanf("%lld %lld", &x1, &x2);
ch1=to_string(x1);
ch2=to_string(x2);
}while((ch1.length()>pow(10,5)) || (ch2.length()>pow(10,5)));
t1[i]=x1;
t2[i]=x2;
i++;
}while(i<n);
for(i=0;i<n;i++){
s=t1[i]+t2[i];
cout<<s<<endl;
}
return 0;
}
can't find a solution please help! and thx in advance!
example input:
1
14444444444444444111115556
55656464684646464646647676
output
-2
//edit:
Is there a way to calculate the sum of 100000 :) decimal digits numbers like the ones in the example using standard libraries ?
Fundamental integral types such as long long have limited range that they can represent. If a calculation causes results in a larger result than can be represented, it will overflow. Signed integer overflow has undefined behaviour in C++.
It is possible to represent an infinite range of numbers (in theory, memory limits the practice) by using an array of integers to represent different parts of the number. This technique is called arbitrary precision arithmetic.
There is no implementation of arbitrary precision types in the C++ standard library, so either you must implement one yourself, or you can use a library implemented by others.

How to calculate 2 to the power 10000000 [duplicate]

This question already has answers here:
Store and work with Big numbers in C
(3 answers)
Closed 6 years ago.
How to calclute 2 to the power 10000000 without crashing the compiler. What shoud be data type for extramily big integer in c/c++.
For the very specific value 2 raised to the power of 1000 a double is sufficient.
#include <stdio.h>
#include <math.h>
int main(int argc, const char *argv[]) {
printf("%f\n", pow(2., 1000));
return 0;
}
In general however you will need to implement an arbitrary precision multiplication algorithm to compute numbers that big (or use a library that provides that).
C++ has no predefined standard functions for this kind of computation.
If you want to implement your own version as an exercise then my suggestion is to use numbers in base 10000. They're small enough that single-digit multiplication won't overflow and it's very easy and fast to translate the result into decimal at the end because you can just map base-10000 digits to decimal without having to implement division an modulo too.
Also to compute such a big power (10,000,000) you will need to implement power by squaring, i.e.
BigNum pow(BigNum a, int b) {
if (b == 0) {
return 1;
} else if (b & 1) {
return a*pow(a, b-1);
} else {
BigNum x = pow(a, b/2);
return x*x;
}
}
this will allow to compute pow(a, b) with O(log(b)) instead of O(b) multiplications.
Store the digits in an int array where each location of the array denotes one digit. Then multiply them repetitively. That way you will get the answer with out crashing the compiler.
Well you need 302 locations for that. And the multiplication is simply the one that we do in grade classes. You have implement it in coding.
Little bit of code
int d[400];
for(int i=0;i<399;i++)
d[i]=0;
d[0]=1;
int carry=0;
int temp=0;
for(int j=0;j<=999;j++)
{
carry=0;
temp=0;
for(int i=0;i<=399;i++)
{
temp=d[i]*2+carry;
d[i]= temp%10;
carry = temp/10;
}
}
print d[0..399] in reverse order trimming zeroes.
Unlike Python/Java, C++ does not handle such big number by itself nor does it have a dedicated data type for it. You need to use an array to store the numbers. You do not have a data type for the problem. These kind of questions are common in competitive programming sites. Here is a detailed tutorial.
Large Number in C/C++
You can also learn about bit manipulation. They are handy when you multiply by 2.
Please read this before using pow(2., 1000) as mentioned in another answer.
c++ pow(2,1000) is normaly to big for double, but it's working. why?
As #6502 cleraly puts it in his answer, it can be used for this specific case of 2^1000. I missed that, be careful about that in case you are going to use this in a competitive programming site.

Calculating large power of a number

#include<iostream>
#include<cstdio>
#define M 1000000007
using namespace std;
long long int power(int a,int b)
{
if(b==0)
return 1;
else if(b==1)
return a;
else if(b%2==0)
return power((a*a)%M,b/2);
else
return (power((a*a)%M,b/2)*a)%M;
}
In this function when I pass a=2, b>31, it always returns 0.for b=31 i got 147483634.can you tell where the problem is?
or can you tell another method for calculating large powers of a number.
In (a*a)%M, a*a probably overflows before computing the remainder. And starting with 2, the overflow producing 0 doesn't surprise me. You need to work with a type able to represent (M-1)*(M-1), i.e. 1000000012000000036 while int is commonly limited to 2147483647. long long (standard in C since 99 and C++ since 11, common extension elsewhere) is guaranteed to work.
Under <cmath> there's pow(x,y) in which x is the base and y is the exponent. x^y.
Reference here
When a is an int, a*a uses int-sized arithmetic. Try a*(long long)a instead, to use wider arithmetic that won't overflow.

Creating custom data type in c++

I'm writing a program to find the value of pi, and want it to show more than the standard 16 decimal places.
How do I create a variable that can hold more than 16 decimal places?
My current program is written below.
Using Dev-C++:
#include<iostream.h>
#include<conio.h>
#include<math.h>
int factorial(int a)
{
int b=1,c=1;
for(c; c<=a; c++)
{
b=b*c;
}
return b;
}
int main()
{
cout.precision(300);
long int n,a;
long double z=0,pi,num,den;
for(n=0; n<1000000; n++)
{ //begin for
num=(pow(factorial(2*n),3))*((42*n)+5);
den=(pow(factorial(n),6))*(pow(16,(3*n)+1));
z=z+(num/den);
pi=1/z;
if(n%1==0)
{
cout<<z<<endl; //test print statement
cin>>a;
cout<<pi;
cout<<endl;
}
}
getch();
return 0; //end for
}
If you don't want to use an existing high-precision arithmetic library, then here are a few pointers for writing your own. It will be a fair amount of work (and quite fiddly to debug), but quite a good learning exercise if you've got the time.
Store each number as an array of smaller "digits". For a very simple (but inefficient) implementation, these could literally be decimal digits, with values from 0 to 9 - this will then be very easy to print. For a more efficient implementation, I'd probably use 32-bit values for the "digits". You'll also need to decide how to represent negative numbers, whether the array should be fixed or variable size, and (for working with non-integers) whether the decimal point should be fixed or floating.
Implement basic arithmetic using the algorithms you learnt in primary school: addition with carry, subtraction with borrow, long multiplication and long division.
pow and factorial, needed for your algorithm can be implemented simply as repeated multiplication; other algorithms are available if this isn't fast enough (and for functions like sqrt and sin that can't be represented exactly with basic operations).
Sounds like you want a bignum library. Have a look at the GNU Multiple Precision Arithmetic Library for a widely-used open source alternative.
You can use one of the bigint libraries on the internet, for example: https://mattmccutchen.net/bigint/