I was trying to find the lcm of two numbers and for one of the input cases (28851539 and 1183019) my program returns a negative value . Apparently it is not able to compute (28851529*1183019)/9 .
#include <iostream>
long long gcd(int a, int b) {
long long int temp;
if(a%b==0)
{
return b;
}
else
{
temp=a%b;
return gcd(b,temp);
}
}
long long lcm(int a, int b , int g) {
//std::cout<<g;
long long int f=(a*b)/g;
return f;
}
int main() {
long long int a, b;
std::cin >> a >> b;
long long int g = gcd(a,b);
long long int q=lcm(a, b, g);
std::cout << q << std::endl;
return 0;
}
How do i compute that accurately ?
You problem is
long long int f=(a*b)/g;
since all of the types in (a*b)/g are int then this will be calculated as an int and if an int is 16 or 32 bits then it will overflow. Do note that since you have signed types this is actually undefined behavior. To get around this you either need to make a, b or g a long long int or you can change the parameters of the function to make them all long long ints.
long long int lcm(long long int a, long long int b , long long int g)
I would also suggest you use an unsigned long long int if you are not dealing with negative numbers. If you are not then you can use the type uint64_t from <cstdint> otherwise int64_t to make the type names shorter.
Related
It might not be like other asked questions in stackoverflow. In this problem, it works fine, but in one case, it returns wrong answer. I'm trying to solve the logical issue of this program.
I wrote a program to calculate the sum of this:
x, n, a would be entered by the user:
Here is my program:
#include <iostream>
long long int unsigned fact (long long unsigned int a);
long long int unsigned comb (long long unsigned int n, long long unsigned int r);
long long unsigned intpower (long long unsigned int a, long long unsigned int n);
using namespace std;
int main()
{
int n;
long long unsigned int x, a;
cin >> a >> x >> n;
long long unsigned int sum = 0;
for (int i = 0; i <= n; i++) {
sum += comb(n, i)*intpower(x, i)*intpower(a, (n-i));
}
cout << sum;
return 0;
}
// Calculates Factorial
long long int unsigned fact (long long unsigned int a) {
long long int unsigned p = 1;
for (long long unsigned int i = 1; i <= a; i++) {
p *= i;
}
return p;
}
// Calculates the combination
long long int unsigned comb (long long unsigned int n, long long unsigned int r) {
return (fact(n)/fact(r)/fact(n-r));
}
long long unsigned intpower (long long unsigned int a, long long unsigned int n){
long long unsigned int p = 1;
for (long long unsigned int i = 1; i <=n ; i++){
p *= a;
}
return p;
}
But in one case, my program returns wrong answer. Here's the test done my a website that verifies the written programs for problems:
Do you guys have any idea why I got wrong answer in one test? The thing is I don't know what numbers would be entered in test 1, but there should be a logical issue that it gives wrong answer in one case.
Kind regards.
As the comments have pointed, the failing test case is most probably because of a corner-side with the maximum values of the inputs. The range that you can store in a long long int data type (if your compiler support the type) is from -9,223,372,036,854,775,807 to 9,223,372,036,854,775,807. It means that if in your case you have x, a and n as their maximum values, you will have an overflow. For an example, the output of your code with the following inputs is the same:
for:
int n = 10;
long long unsigned int x = 9999999999;
long long unsigned int a = 1000000000;
output is: 9223372036854775808
int n = 10;
long long unsigned int x = 1000000000;
long long unsigned int a = 1000000000;
the output is again: 9223372036854775808
Can somebody explain where the mistake is in this code? because when I use parameters like this a=425 b=9631 n=9876543215 I get "exited,segmentation fault code 139" :(
#include <iostream>
#include <iomanip>
using namespace std;
void ivedimas(long long &n, long long &a, long long &b);
long long fib(long long n, long long a, long long b);
void isvedimas(long long ats);
int main()
{
long long n,a,b;
ivedimas(n,a,b);
isvedimas(fib(n,a,b));
return 0;
}
void ivedimas(long long &n, long long &a, long long &b)
{
cin>>a>>b>>n;
}
long long fib(long long n,long long a, long long b)
{
long long c=b-a;
if (n==2)
return c;
return fib(n-1,b,c);
}
void isvedimas(long long ats)
{
cout<<ats<<endl;
}
Stack Overflow: every time the function calls itself it adds to the stack, so this solution works for small numbers, but anything too large it will fail.
Iterative solution:
long long fib(long long n, long long a, long long b)
{
if (n == 0) {return 0;}
if (n == 1) {return 1;}
long long t = 0;
long long j = 1;
for (int i = 2; i <= n; i++) {
int k = j;
j += t;
t = k;
}
return j;
}
This recursive version of Fibonacci is not good with large number. Each time it's called the recursion the stack increse and never decrese till the end. So you just terminate the process memory before the result is return.
You can try an iterative solution.
thank you, this is the solution:)) every 6th number in the sequence is the same :)
e.g. 10,8,-2,-10,-8,2|10,8,-2,-10,-8,2...
long long fib(long long n,long long a, long long b)
{ long long c=a;
if (n==0) return a;
if (n%6==1) return b;
for (int i=1;i<n%6;i++)
{
c=b-a;
a=b;
b=c;
}
return c;
}
I made a program for codechef and its wrong apparantly (although all tests have been positive). The code is:
#include <iostream>
using namespace std;
int g (int a,int b){
return b == 0 ? a : g(b, a % b);
}
int l (int a, int b){
return (a*b)/(g(a,b));
}
int main() {
int n;
cin >> n;
int a[n],b[n];
for (int x = 0;x<n;x++){
cin >> a[x] >> b[x];
}
for (int x = 0;x<n;x++){
cout << g(a[x],b[x]) << " "<< l(a[x],b[x]) << endl;
}
return 0;
}
Codechef won't tell me what integers dont work, and im pretty sure my gcd function is legit.
Since gcd is properly defined as the largest non-negative common divisor, you can save yourself the annoying details of signed division, e.g.,
static unsigned gcd (unsigned a, unsigned b)
{
/* additional iteration if (a < b) : */
for (unsigned t = 0; (t = b) != 0; a = t)
b = a % b;
return a;
}
Likewise for lcm; but the problem here is that (a*b) may overflow. So if you have two large (signed) int values that are co-prime, say: 2147483647 and 2147483629, then gcd(a,b) == 1, and (a*b)/g overflows.
A reasonable assumption on most platforms is that unsigned long long is twice the width of unsigned - although strictly speaking, it doesn't have to be. This is also a good reason to use exact types like [u]int32_t and [u]int64_t.
One thing you can be sure of is that a/g or b/g will not cause any issues. So a possible implementation might be:
static unsigned long long lcm (unsigned a, unsigned b)
{
return ((unsigned long long) a) * (b / gcd(a, b)));
}
If your test values are 'positive' (which is what I think you mean), you can cast them prior to (unsigned) prior to call. Better yet - replace all your int variables with unsigned int (though the loop variables are fine), and save yourself the trouble to begin with.
My code is the following:
#include <iostream>
int gcd(int a, int b) {
//write your code here
if(a==0){
return b;
}else if(b==0){
return a;
}else if(a>b){
int a_pri=a%b;
return gcd(b,a_pri);
}else if(a<b){
int b_pri=b%a;
return gcd(a,b_pri);
}else{
return a;
}
}
long long lcm(int a, int b) {
int temp_gcd = gcd(a,b);
long long abproduct = a*b;
long long result = abproduct/temp_gcd;
return result;
}
int main() {
int a, b;
std::cin >> a >> b;
std::cout << lcm(a,b) << std::endl;
return 0;
}
I would like to output the largest common multiple of two numbers.
but as I input two numbers 14159572 63967072 ,It output a negative number -527892768.But the correct answer should be 226436590403296.
It looks like the output is cut off to 32bit.
so ,I print the variable temp_gcd ,it is 4.I changed the expression
long long result = abproduct/temp_gcd;
to
long long result = abproduct/4;
Then it outputs the right answer.
The problem is on the line long long abproduct = a*b;
Since a and b are both int, any operation on them will result in an int, which will result in an overflow in this case. Try casting either a or b to long long when doing the calculation.
long long abproduct = (long long)a * b;
You're performing an int multiplication because that's the data type of the operands. Change that data type. I.e., change
long long lcm(int a, int b)
to
long long lcm(long long a, long long b)
Don't take the advice to use casts: a cast should always be the measure of last resort, like going to war (only after politicians and diplomats fail).
If you don't change the function signature then you can force a conversion by replacing a*b with 1LL*a*b. But I don't recommend that here. Using proper data types is the right way to go.
Still, the code
long long abproduct = a*b;
long long result = abproduct/temp_gcd;
needlessly adds cases where the result can overflow. To reduce that,
long long result = a*(b/temp_gcd);
noting that this can't discard information (in general, though, you have to be careful about integer division discarding information).
Didn't want to edit the #MahlerFive's answer - that should work too. I would cast a and b to long long like-so: long long abproduct = static_cast<long long>(a)*static_cast<long long>(b).
Suppose I have two long longs, a and b, that I need to multiply, then get the value mod k for some large k, such that a, b, and k are all in the range of long long but not of int. For simplicity, a, b < k.
Thus the code would be:
long long a, b, k;
cin >> a >> b >> k;
cout << (a * b)%k << "\n";
However, since a and b are so large, if you multiply like above, and it overflows and becomes negative, then mod k would be a negative number and incorrect.
How can you ensure that the value mod k is correct?
Edit: As a bonus, how does this work in Java? Is it the same, as expected? Or is BigInteger needed?
Many compilers offer a 128-bit integral type. For example, with g++ you can make a function
static inline int64_t mulmod(int64_t x, int64_t y, int64_t m)
{
return ( (__int128_t)x * y) % m;
}
Aside: if you can, try to stick to unsigned integer types when you're doing modular arithmetic. The rounding behavior of integer division makes using % very awkward when signed values are involved.
If you know the values are less than ULONGLONG_MAX/2 (so an add won't overflow), you can do the multiply one bit at a time:
unsigned long long mulmod(unsigned long long a, unsigned long unsigned long b, long long m) {
unsigned long long rv = 0;
a %= m;
b %= m;
while (b) {
if (b&1) { rv += a; if (rv >= m) rv -= m; }
a += a; if (a >= m) a -= m;
b >>= 1; }
return rv; }
If you know you're running on gcc/x86_64, you could try:
unsigned long mulmod(unsigned long a, unsigned long b, unsigned long m) {
unsigned long rv;
asm ("mulq %2; divq %3" : "=d"(rv), "+a"(a): "S"(b), "c"(m));
return rv;
}
which will work up to ULONG_MAX
If your numbers get bigger than that, you'll need to go to a multiprecision library such as GMP