简体   繁体   中英

Another way to calculate cube root in C#

In my calculator I am using these statements to calculate square root and cube root.

case "sqrt root":
        result = Math.Sqrt(number1);
break;
case "root":
     result = Math.Pow(number1, (1 / number2));
     //"for cubic root" - Math.pow(number, (1/ 3))
break;

I am not very familiar with Math.Pow. Is there another way to calculate cube root? With Math.Sqrt?

You'd need to do it with floating point division (doing 1/3 does integer division, which wouldn't work)

result = Math.Pow(number, (1.0 / 3.0));

But otherwise no, there's no built-in function for cubic root

I somewhere saw how to do cube root with math.sqrt, so I think maybe someone will know here or show me another way, how to do cubic root. user3841611

Mathematically, you can use Sqrt to get the cube root:

x 1/3 = x 1/4 * x 1/16 * x 1/64 * x 1/256 * x 1/1024 * x 1/4096 * x 1/16384 *...

This comes from the binary representation of 1/3 and the fact that:

  • Sqrt(x) is x 1/2 ,
  • Sqrt(Sqrt(x)) is x 1/4 ,
  • Sqrt(Sqrt(Sqrt(x))) is x 1/8 etc..
  • Sqrt(Sqrt(Sqrt(Sqrt(x)))) is x 1/16 etc..

In other words, you'd keep taking the square root of your number and multiply every other value to get x 1/3 . Once the value stops changing (there are limits to floating point precision, so eventually the product won't change), you'll have something very close to x 1/3 .

I'll post some pseudo code if you wish.

Finding the cube root by multiplying its nesting fourth roots looks okay but assert fails.

    static double Sqrt(double x)
    {
        if (x < 0)
            throw new OverflowException("Cannot calculate square root from a negative number");

        double epsilon = 0.0;
        double current = Math.Sqrt(x), previous;
        do
        {
            previous = current;
            if (previous == 0.0)
                return 0;
            current = (previous + x / previous) / 2;
        }
        while (Math.Abs(previous - current) > epsilon);
        return current;
    }

    // Mathematically, you can use Sqrt to get the cube root:
    // x1/3 = x1/4 * x1/16 * x1/64 * x1/256 * x1/1024 * x1/4096 * x1/16384 *...
    static double Cbrt(double value)
    {
        if (value.Equals(1.0))
            return value;

        double nextValue = Sqrt(Sqrt(value));
        return nextValue * Cbrt(nextValue);
    }

    public static void Main(string[] args)
    {
        string question = "Why does the cube root of {0:0.000} not equal between {1:0.000000000} and {2:0.000000000} ?";
        double value = 2.197, cbrt1 = Cbrt(value), cbrt2 = Math.Pow(value, 1.0 / 3.0), difference = Math.Abs(cbrt1 * .000000001);
        System.Diagnostics.Debug.Assert(Math.Abs(cbrt1 - cbrt2) > difference, string.Format(question, value, cbrt1, cbrt2));
        value = 125.0; cbrt1 = Cbrt(value); cbrt2 = Math.Pow(value, 1.0 / 3.0); difference = Math.Abs(cbrt1 * .000000001);
        System.Diagnostics.Debug.Assert(Math.Abs(cbrt1 - cbrt2) > difference, string.Format(question, value, cbrt1, cbrt2));
        value = 343.0; cbrt1 = Cbrt(value); cbrt2 = Math.Pow(value, 1.0 / 3.0); difference = Math.Abs(cbrt1 * .000000001);
        System.Diagnostics.Debug.Assert(Math.Abs(cbrt1 - cbrt2) > difference, string.Format(question, value, cbrt1, cbrt2));
    }

.NET Core has Math.Cbrt :

result = Math.Cbrt(number);

This is not available in .NET Framework 4.8.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM