-4

As i was trying to find gcd of large numbers in which one number is 10^250 and other is like between 100000. While trying to do that in c++ am getting one error which i am not able to figure out but same code in python3 works fine.

#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
ll gcd(ll n,ll mod)
{
    if(!n)
    return mod;
    return (mod%n,n);
}
ll getmod(ll n,char b[])
{
    ll mod = 0;
    for(int i =0;i<strlen(b);i++)
    {
        mod = mod * 10 + b[i];
        mod %= n;
    }
    return mod;
}
int main() {
    // your code goes here
    ll n;
    string m;
    cin>>n;
    getline(cin, m);
    int mod = getmod(n,m);
    int result = gcd(n,mod);
    cout<<result;
    return 0;
}

Output

prog.cpp: In function 'int main()':
prog.cpp:26:22: error: cannot convert 'std::__cxx11::string {aka std::__cxx11::basic_string<char>}' to 'char*' for argument '2' to 'll getmod(ll, char*)'
  int mod = getmod(n,m);
                      ^
Neil
  • 21
  • 3
  • Why `b` is not `string`? –  Jul 30 '19 at 01:23
  • 4
    `#include` Don't do this. Use the proper header. Second `string` -- is this `std::string`? If so, why are you treating it as if it's a `C` char array? They are not the same thing. Last, `typedef long long int ll;` -- it seems you're not familiar with C++, but are picking up very bad coding habits from the start. – PaulMcKenzie Jul 30 '19 at 01:25
  • 1
    `return (mod%n,n);` -- What are you trying to do here? Also, as of C++ 17, there is a `std::gcd` function. This is why all of that `#include – PaulMcKenzie Jul 30 '19 at 01:34
  • The error message is a bit cryptic but contains everything you need to know: *cannot convert* means the compiler has no method it can use to transform type A into type B. *for argument '2'* means the problem is with argument 2. Argument 2 is `m`, and `m` is a `string`. `ll getmod(ll n,char b[])` is expecting a `char []`, not a `string`. This leads back to @dyukha 's comment asking why `b` is not a `string`. `string b` is the most obvious way to pass `string m`, and it'll work. – user4581301 Jul 30 '19 at 02:01
  • The compiler will likely even clean up [the copying involved](https://stackoverflow.com/questions/373419/whats-the-difference-between-passing-by-reference-vs-passing-by-value) for you, byut you can make that explicit by using `const string &b` and pass by reference. The `const` is there to promise that the function will not change `b`, allowing the compiler extra latitude in optimizing and allowing the use of temporary or constant values. – user4581301 Jul 30 '19 at 02:03
  • 1
    Touching on What @PaulMcKenzie is getting at, translating code from one language to another is one of the harder things to do in programming. Code is the description of the behaviour of a program. It is NOT necessarily a list of instructions to be executed. As a result, the code to perform an action in one language can be very different from the code in another language. In order to efficiently translate code, you need to understand the behaviour and translate the behaviour. You cannot do this if you do not understand both languages. – user4581301 Jul 30 '19 at 02:09
  • 1
    Making this even more fun, C++ follows the [As If Rule](https://en.cppreference.com/w/cpp/language/as_if): If the observable behaviour of a program is unchanged, the compiler can do whatever it wants. This results in very fast programs, but the output instructions look almost nothing like the input. It is possible to create a very complicated bit of code that can be transformed into a single runtime operation, something that screws up just about everyone when they first start benchmarking code and need to slow down program execution with repetitive tasks to get good average measurement. – user4581301 Jul 30 '19 at 02:13

1 Answers1

-1

You can use the following program to calculate GCD of two numbers where one of them is very big and the other fits in the int or long long data type.

#include <iostream>
#include <algorithm>

int calculateRemainder(std::string dividend,int divisor){
    int remainder = 0;

    for(int i = 0 ; i < dividend.size() ; ++i){
        remainder = (remainder * 10 + (dividend[i] - '0')) % divisor;
    }

    return remainder;
}

int calculateGCD(std::string a, int b){
    int remainder = calculateRemainder(a,b); // only one call to calculateRemainder is needed,
                                            // after that the gcd calculation is trivial
                                            // because gcd of two numbers is never greater than the minimum of two
    return std::__gcd(b, remainder);
}

int main(){
    std::string a;  // can be very big, in the order of 10^250 or more
    int b; // <= 10^9
    std::cin >> a >> b;
    int result = calculateGCD(a,b);
    std::cout << result << "\n";
    return 0;
}
Robur_131
  • 374
  • 5
  • 15