19

I am working on a way to calculate the nth root of a number. However, I am having problems with the nth root of negative numbers.

Most people say to use Math.pow(num, 1 / root), but this does not work for negative numbers.

I have tried this:

public static double root(double num, double root) {
    if (num < 0) {
        return -Math.pow(Math.abs(num), (1 / root));
    }
    return Math.pow(num, 1.0 / root);
}

but, it does not work for all numbers as the root can be a decimal. For example root(-26, 0.8) returns -58.71, but that is an invalid input. This will also give the wrong answer for even roots. For example root(-2, 2) returns -1.41421, but -2 does not have a square root.

Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138
Will
  • 19,661
  • 7
  • 47
  • 48

8 Answers8

18

(num) ^ (1/root) is similar to exp( (1/root) * log(num) ), so you can do it like:

public static double root(double num, double root)
{
    return Math.pow(Math.E, Math.log(num)/root);
} 
Eng.Fouad
  • 115,165
  • 71
  • 313
  • 417
  • 1
    ` return Math.pow(Math.E, Math.log(num)/root); ` Eng Fouad your method does not provide a correct answer.Proper code should be written like this `Math.pow(Math.exp (1/root),Math.log(num)); ` – Iliya Gino Jan 10 '12 at 13:10
  • @IliyaGino - I think the variable name `root` is not the root itself, but is the inverse of the desired power (so, for example, if `root == 2`, then calling `root(3.0, 2)` should return the square root of 3. – Ted Hopp Jun 04 '13 at 16:43
  • I tried to use your code, it returns 1.9999999998 instead of 2 for the square root of 4, root(4,2). How to make it return 2. Cheers – Jarana Manotumruksa Mar 20 '15 at 15:46
  • 3
    @FeayJaranaManotumruksa You can't expect a floating point function to give an exact answer. It's just not going to happen. – Teepeemm Jul 23 '15 at 13:59
  • This is the correct one – phamductri Sep 26 '22 at 03:42
10

What are you trying to do? Unless you're planning to fully and properly handle complex numbers you cannot take the nth root of a negative number.

For example, while (-8)^(1/3) has a principal branch of -2, the only branches of (-4)^(1/2) are 2i and -2i.

To handle this properly you need to transform the number into its polar form and then take the required root in that form.

So -8 is the complex number 8*exp(i*pi). The 1/3 roots of that are 2*exp(i*pi/3), 2*exp(i*pi), and 2*exp[i*(-pi)/3]. Then you can use de Moivre' formula to compute the roots in the form a + bi.

QuantumMechanic
  • 13,795
  • 4
  • 45
  • 66
2

I use the method below. Maybe it's not the most accurate, but it works well in my case.

public double root(double num, double root) {
    double d = Math.pow(num, 1.0 / root);
    long rounded = Math.round(d);
    return Math.abs(rounded - d) < 0.00000000000001 ? rounded : d;
}
Pavel Kataykin
  • 1,527
  • 15
  • 14
2

Either use one of the many complex number packages available on the Internet, or convert your number to a rectangular position on the Argand plane, rotate it the appropriate angle as given by the root, then read it out as a (real, imaginary) pair.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
0

You could do if(num < 0){ return Math.abs(Math.pow(num, 1 / root)) } Then just use ' + "i"' whenever stating the value. Or use the absolute value for equations and later factor in the positive/negative and i when needed. That's what worked for me.

  • But this will lead to buggy code, since the function won't indicate whether its returned value is real or purely imaginary. – Teepeemm Jul 23 '15 at 14:03
0
    public double root(double num, double root) {
        double y=1;
        double x;
        while(Math.pow(x, root) != num) {
            if(Math.pow(x, root) > num) {
                x=x-y;
                y=y/10;
            } else {
                x=x+y;
            }
        }
        return x;
    }   

This should work fine for you, although it isn't compact it uses as little math functions as possible.

Lorenz Meyer
  • 19,166
  • 22
  • 75
  • 121
0

I'm not too sure about the exact code, but add an extra if statement to clarify between odd and even roots. something along the lines of

public static double root(double num, double root) {
    if (num < 0) {
        if(root%2==1) {
            return -Math.pow(Math.abs(num), (1 / root));
        }
    }
    return Math.pow(num, 1.0 / root);
}

Not entirely sure if this will work with your other code, but I hope it can help

-2

System.out.println( Math.pow(10, Math.log10(Number)/root));

  • 3
    Yes, but we prefer you include some english explaining your answer. (And you want `num`, not `Number`.) – Teepeemm Jul 23 '15 at 13:56
  • @Teepeemm I was providing a logic now it's upto you to make your own theories, bro I am not a teacher who will explain you everything. – Rohit Kumar Jun 04 '19 at 06:36
  • Also, `Math.log10(num)` will fail for `num<0`, which is the whole point of the question. – Teepeemm Jun 04 '19 at 11:45