Search code examples
c++pow

Error while using pow() in C++


I was trying to solve a function problem in which I had to count the number of times digit 1 appeared in all non-negative integers less than n(given).

Here's my code:

int ones(int n, int d)
{
    int rounddown = n - n % pow(10, d+1);
    int roundup = rounddown + pow(10, d+1);
    int right = n % pow(10, d);
    int dig = (n/pow(10, d)) % 10;
    if(dig<1)
        return rounddown/10;
    else if(dig==1)
        return rounddown/10 + right + 1;
    else
        return roundup/10;
}

int countDigitOne(int n) {

    int count = 0;
    string s = to_string(n);
    for(int i=0;i<s.length();i++)
    count+=ones(n, i);   
    return count;        
}

But the following compilation error shows up:

Line 3: invalid operands of types '__gnu_cxx::__promote_2::__type {aka double}' and 'int' to binary 'operator%'


Solution

  • The main problem is type conversion. The result of pow is double. The modulo operator does not work for double. You need to take fmod.

    Fix your line 3 like this:

    int rounddown = (int)(n - fmod(n, pow(10, d +1));
    

    Because your values are all in the domain of integer you can also use:

    int rounddown = n - n % (int)(pow(10, d + 1));
    

    as suggested by others.


    Just for completeness ... If you are not forced to use an arithmetic approach you can just char compare:

    #include<iostream>
    #include<string>
    
    using namespace std;
    
    int countOnesInNumber(string s)
    {
        int res = 0;
        for(int i = 0; i < s.length(); i++)
        {
            if(s[i] == '1')
            {
                res++;
            }
        }
        return res;
    }
    
    long countOnes(int upper)
    {
        long result = 0;
        for(int i = 0; i < upper; i++)
        {
            result += countOnesInNumber(std::to_string(i));
        }
        return result;
    }
    
    int main()
    {
        string in;
        cout << "Please enter a number:";
        cin >> in;
        cout << endl;
        cout << "you choose:" << in << endl;
        int n = stoi(in);
        cout << "there are " << countOnes(n) << " ones under " << n << endl;
    
        cin.ignore();
        cin.get();
    }
    

    There is also a more sophisticated approach. The digits repeat for every magnitude. There is 1 one under 10, there are 10 times 1 one under 100 plus another 10 ones for the number 10...19. And so on. You can just calculate the number of ones under a given magnitude with:

    int exp = (int)log10(n);
    int ones = exp * (int)pow(10, exp - 1);
    

    where n must be a magnitude of 10 (eg. 10, 100, 1000, 10000 ...). If you are good at maths you might even find a complete closed formula.