Overflow in long long int - c++

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.

Related

Fast Multiplication on SPOJ

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.

Print precise value of pow() function in c++

my output is coming wrong. I guess i'm wrong with casting. please help me out.
int n;
cin>>n;
unsigned long long int a,s;
cin>>a;
s=(2*pow(10,n)+a);
But when I am giving large n like 17 or 18 then my output which is s is not coming as expected.
see image for output
e.g: when n=17, a=67576676767676788 then s=267576676767676800 which ideally should be 2*10^17 + 67576676767676788
First you have to understand what is going on.
To be able to use std::pow, compiler silently converts integer types to double and returned value is a double too.
Note that double has 16 significant digits (in decimal representation).
When you do assignment, conversion of double to long long int is silently performed
unsigned long long int - if this type has 64 bits the maximum power of 10 is 19
Now if you want to exceed this limitation you should use an external library. gmp is quite nice.
If it is acceptable to have a limitation from range of unsigned long long int just implement your own power function.

I want to get output 2^64 without any extension in C++

thanks for checking this question.
so i wonder how can i get output 2^64, if i input is 2^64.
in unsigned long long int, it just only reach 2^64-1 == 18446744073709551615
the point is, when input number == 18446744073709551616
the output will be "2^64"
but code that i have is :
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
unsigned long long int a;
cin >> a;
if (a == pow(2,64))
{
cout << "2^64";
}
}
so the problem is, if i input : 18446744073709551616
it will no output. how can i make the output "2^64"?
unsigned long long is 64-bits or larger. That means in some machines, it is going to be just 64-bits. In this case, you will have overflow problem in your code.
Check ULLONG_MAX (#include <climits>)
Maximum value for an object of type unsigned long long int 18446744073709551615 (2^64-1) or greater*
the actual value depends on the particular system and library implementation, but shall reflect the limits of these types in the target platform.
(From http://www.cplusplus.com/reference/climits/ ).
This means your target platform supports 64 bit unsigned long long values. Thus your limit is 2^64-1.
You can try using a big integer library, like this to work around the limitation.
The largest data type in c++ differs from compiler to compiler...but generally unsigned long long int is of course considered large!!
So to solve ur problem..,better change the if condition to pow(2,64)-1...
Other than that if you really wanna implement that condition in your project, u add a "Do u mean condition..like do u mean 'thenumber+1' ?? "and proceed..;)

tgamma() long long typecasting

I am writing a function in which I have to calculate factorial of numbers and do operations on them.The return value of the function should be long long so I think it would be better to do all operations in long long format. If I am wrong please correct me.
The tgamma() function by itself returns the correct value in scientific notation. But the the value returned by tgamma() is sometimes 1 less than actual answer when the value returned by the function is typecasted to 'long long'.
int main()
{
std::cout<<"11!:"<<tgamma(12)<<std::endl;
std::cout<<"12!"<<tgamma(13)<<std::endl;
std::cout<<"13!"<<tgamma(14)<<std::endl;
std::cout<<"14!"<<tgamma(15)<<std::endl;
std::cout<<"15!"<<tgamma(16)<<std::endl;
std::cout<<"16!"<<tgamma(17)<<std::endl;
std::cout<<"********************************"<<std::endl;
std::cout<<"11!:"<<(long long)tgamma(12)<<std::endl;
std::cout<<"12!"<<(long long)tgamma(13)<<std::endl;
std::cout<<"13!"<<(long long)tgamma(14)<<std::endl;
std::cout<<"14!"<<(long long)tgamma(15)<<std::endl;
std::cout<<"15!"<<(long long)tgamma(16)<<std::endl;
std::cout<<"16!"<<(long long)tgamma(17)<<std::endl;
return 0;
}
I am getting the following output:
11!:3.99168e+07
12!4.79002e+08
13!6.22702e+09
14!8.71783e+10
15!1.30767e+12
16!2.09228e+13
********************************
11!:39916800
12!479001599
13!6227020799
14!87178291199
15!1307674367999
16!20922789888000
The actual value of 15! according to this site is 1307674368000 but when I typecast tgamma(16) to long long, I get only 1307674367999. The thing is this discrepancy only appears for some numbers. The typecasted answer for 16! is correct - 20922789888000.
This function is for a competitive programming problem which is currently going on, so I can't paste the function and the solution I am developing to it here.
I would roll my own factorial function but I want to reduce the number of characters in my program to get bonus points.
Any tips on how to detect this discrepancy in typecasted value and correct it? Or maybe some other function that I can use?
Obviously, unless we have very unusual implementation, not all long long numbers can be exactly represented as double. Therefore, tgamma cannot store double values such that casting to long long would produce exact value. Simply there are more long long values than double values within long long interval.
If you want exact long long factorial, you should implement it yourself.
On top of this, if you want precision, you transform double to long long not as (long long)x, but as (long long)round(x), or (long long)(x+0.5), assuming x is positive.
Casting from a floating point type to an integral type truncates. Try (long long) roundl(tgammal(xxx)) to get rid of integer truncation error. This is also using long doubles so it may give you more digits.
#include <math.h>
#include <iostream>
int main(){
std::cout<<"11!:"<<(long long)roundl(tgammal(12))<<std::endl;
std::cout<<"12!"<<(long long)roundl(tgammal(13))<<std::endl;
std::cout<<"13!"<<(long long)roundl(tgammal(14))<<std::endl;
std::cout<<"14!"<<(long long)roundl(tgammal(15))<<std::endl;
std::cout<<"15!"<<(long long)roundl(tgammal(16))<<std::endl;
std::cout<<"16!"<<(long long)roundl(tgammal(17))<<std::endl;
std::cout<<"********************************"<<std::endl;
std::cout<<"11!:"<<(long long)roundl(tgammal(12))<<std::endl;
std::cout<<"12!"<<(long long)roundl(tgammal(13))<<std::endl;
std::cout<<"13!"<<(long long)roundl(tgammal(14))<<std::endl;
std::cout<<"14!"<<(long long)roundl(tgammal(15))<<std::endl;
std::cout<<"15!"<<(long long)roundl(tgammal(16))<<std::endl;
std::cout<<"16!"<<(long long)roundl(tgammal(17))<<std::endl;
return 0;
}
Gives:
11!:39916800
12!479001600
13!6227020800
14!87178291200
15!1307674368000
16!20922789888000
********************************
11!:39916800
12!479001600
13!6227020800
14!87178291200
15!1307674368000
16!20922789888000

long and int not enough and double wouldn't work

I am using C++ and I've heard and experienced that the maximum value that can be stored in a int
and a long are same.
But my problem is that I need to store a number that exceed the maximum value
of long variable. The size of double variable is pretty enough.
But the problem is using double variable
avoid me using the operator % which is necessary to code my function more easily and some times there
seems to be no other ways than using it.
So please would you kindly tell me a way to achieve my target?
It depends on the purpose. For a better answer, give us more context
Have a look at (unsigned) long long or GMP
You can use type long long intor unsigned long long int
To know the maximum value that an untegral type can contain you can use the following construction as for example
std::numeric_limits<long long>::max();
To use it you have to include header <limits>
So, you want to compute the modulo of large integers. It's 99% likely you're doing encryption, which is hard stuff. Your question kind of implies that maybe you should look for some off-the-shelf solution for your top-level problem (the encryption).
Anyway, the standard answer is otherwise to use a library for large-precision integers, such as GNU MP.
#include <cmath>
int main ()
{
double max_uint = 4294967295.0;
double max1 = max_uint + 2.0;
double max2 = (max1 + 1.0) * (max_uint + 1.0);
double f = fmod(max2,max1);
return 0;
}
max1 and max2 are both over unsigned int limit, and fmod returns correct max2 % max1 result, which is also over unsigned int limit: f == max_uint + 1.0.
Edit:
good hint from anatolyg: this method works only for integers up to 2^52. This is because mantissa of double has 52 bit, and every higher integer is representable only with precision loss. E.g. 2^80 could be == (2^80)+1 and == (2^80)+2 and so on. The higher the integers, the higher the inprecision, because densitiy of representable integers gets wider there.
But if you just need to have 20 extra bit compared to int with 32 bit, and have no other possibility to achieve this with an built-in integral type (with which the regular % will be faster I think), then you can use this...
first there's a difference between int and long type
but for To fix the your problem you can use
unsigned long long int
here is a list of some of the sizes you would expect in C++:
char : 1 byte
short : 2 bytes
int : 4 bytes
long : 4 bytes
long long : 8 bytes
float : 4 bytes
double : 8 bytes
I think this clearly explains why you are experiencing difficulties and gives you a hint on how to solve them