Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

find cubic root of a number from 0 to 125

Tags:

c

precision

cubic

I am trying to write a C code of a function that takes an integer from 0 to 125 and return the cubic root of that integer only if it's a whole number ( 1,2,3,4,5 ) and if it's not, return 0 instead. So I wrote this code:

unsigned int cubic(unsigned int n) {
    if (n > 125)
        return 0;
    double root = pow(n, (1 / 3.));
    double rem = (double)(roundf(root)) - root;
    if (rem != 0)
        return 0;
    else
       return roundf(root);
}

this function works fine with all cases except for the number 64 and 125. in these cases it returns 0 instead of the cubic roots of these numbers which are 4 and 5 respectively. Can anybody explain to me why this is happening?

like image 847
Ahmed Tarek Avatar asked Dec 18 '25 15:12

Ahmed Tarek


1 Answers

Because 1 / 3. cannot accurately represented as a floating point number, the floating point calculation pow(64, (1 / 3.)) might produce a number very close to 4, but a tiny bit smaller or larger, different enough from 4 for (double)(roundf(root)) - root to be different from 0.

You could work around this precision issue this way:

unsigned int cubic(unsigned int n) {
    int root = (int)round(pow(n, 1 / 3.));
    if (root * root * root == n)
        return root;
    else
        return 0;
}

Instead of pow(n, 1 / 3.), you could use cbrt(n) if available on your system, but the precision issue might still be present.

For your goal, it seems much simpler to iterate over the possible integer roots and check:

unsigned int cubic(unsigned int n) {
    for (unsigned int i = 1; i <= 5; i++) {
        unsigned int i3 = i * i * i;
        if (i3 == n)
            return i;
        if (i3 > n)
            break;
    }
    return 0;
}

Or even more explicit:

unsigned int cubic(unsigned int n) {
    switch (n) {
      case 1 * 1 * 1: return 1;
      case 2 * 2 * 2: return 2;
      case 3 * 3 * 3: return 3;
      case 4 * 4 * 4: return 4;
      case 5 * 5 * 5: return 5;
      default: return 0;
    }
}
like image 102
chqrlie Avatar answered Dec 20 '25 07:12

chqrlie



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!