0

I'm solving an problem where it need to get the difference between the number of even and odd divisors ,and i need to use sqrt() function because the limit of the number is 10^9 so looping on the whole number is not an option cause of the time limit exceed.

this a function I tried to make but it doesn't work perfectly on all number.

Ex. 4 & 48745.

Case 4 : should output 2 even divisors {2,4} and 1 odd divisor {1} -- the below function output 3 even 1 odd

Case 48745 :should output 0 even divisors and 4 odd divisors {1,5,9749,48745} -- the below function output 2 even 2 odd

int di(int x)
{
    int even=0,odd=0;
    for(int i=1;i<=sqrt(x);i++)
    {
        if(x%i==0)
        {
            if(i%2)
                odd++;
            else
                even++;
        if(x/i %2==0 && x/i!=i)
            even++;
        else if(x/i!=i)
            odd++;
        }
    }
    return even-odd;
}
Amr Morsy
  • 27
  • 5
  • 1
    *it doesn't work perfectly on all number* isn't much help as a diagnosis. If you reported some trial inputs, what you expect as output and what you get as output, that would all be much more helpful. The kinds of error your program makes is a very useful diagnostic tool. Heck, you might even figure it out yourself along the way ... – High Performance Mark Dec 17 '15 at 10:14
  • 1
    You are aware of that [`sqrt`](http://en.cppreference.com/w/c/numeric/math/sqrt) takes a floating-point argument, and more importantly returns a floating-point value. Floating point values have all kind of rounding troubles on computers, meaning that you might not get *exactly* what you expect, and then it's *truncated* to an integer for the comparison in your loop. That means a result like e.g. `1.9999566` will be truncated to `1`. – Some programmer dude Dec 17 '15 at 10:16
  • @JoachimPileborg Okay I'll use Ceil() for the floating part but I think there's something is wrong in the algorithm itself – Amr Morsy Dec 17 '15 at 10:18
  • 1
    I think it's odd even to check an odd number for even divisors. – High Performance Mark Dec 17 '15 at 10:35
  • 1
    I don't know what you did in your own code, but the part you provide works perfectly: http://ideone.com/lzkde2 (even without taking care of `sqrt` approximation for these 2 numbers). – Holt Dec 17 '15 at 10:39
  • @Holt That helped me notice the wrong isn't in the loop but the function doesn't return -ve number I return 0-4 it return 0. Doesn't map carry -ve values ? – Amr Morsy Dec 17 '15 at 10:45
  • 1
    This is what debuggers are for. Step through the code, line by line, in a debugger to see what the results of each calculation is. For a small value such as `4` it's very easy and quick. – Some programmer dude Dec 17 '15 at 10:49
  • Your question doesn't make sense. The code only calculates the difference between the number of even and odd divisors. It doesn't return "even divisors" and "odd divisors" separately. – gnasher729 Dec 17 '15 at 11:20

1 Answers1

0

Try more simple code:

#include <iostream>
#include <cmath>

int divdiff(int x)
{
    unsigned int even = 0;
    unsigned int odd  = 0;
    const unsigned int sqrtx = std::sqrt(x);

    for (int i = 1 ; i <= sqrtx ; ++i)
    {
        if (x % i == 0)
        {
            if (i % 2 == 0)
            {
                ++even;
            }
            else
            {
                ++odd;
            }
        }
    }

    even *= 2;
    odd  *= 2;

    if (x == sqrtx * sqrtx)
    {
        if (x % 2 == 0)
        {
            --even;
        }
        else
        {
            --odd;
        }
    }

    std::cerr << __func__ << '(' << x << "): even=" << even << ", odd=" << odd << std::endl;
    return even - odd;
}

int main()
{
    std::cout << divdiff(2*2) << std::endl;
    std::cout << divdiff(2*3) << std::endl;
    std::cout << divdiff(3*3) << std::endl;
    std::cout << divdiff(7*11*13*17*23) << std::endl;
}
YSC
  • 38,212
  • 9
  • 96
  • 149