C#中另一种计算立方根的方法

Another way to calculate cube root in C#

在我的计算器中,我使用这些语句来计算平方根和立方根。

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;

我对Math.Pow不是很熟悉。还有另一种计算立方根的方法吗?用 Math.Sqrt?

你需要用浮点除法来完成(做 1/3 做整数除法,这是行不通的)

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

但除此之外没有,没有立方根的内置函数

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

在数学上,您可以使用 Sqrt 求立方根:

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

这来自 1/3 的 binary representation 以及以下事实:

  • Sqrt(x) 是 x1/2,
  • Sqrt(Sqrt(x)) 是 x1/4,
  • Sqrt(Sqrt(Sqrt(x))) 是 x1/8 等..
  • Sqrt(Sqrt(Sqrt(Sqrt(x)))) 是 x1/16 等..

换句话说,你会保持取你的数字的平方根并乘以所有其他值得到x1/3。一旦值停止变化(浮点精度有限制,所以最终产品不会改变),你将得到 非常接近 x1/ 3.

如果你愿意,我会post一些伪代码。

通过乘以嵌套的四次根来求立方根看起来没问题,但断言失败了。

    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 有 Math.Cbrt:

result = Math.Cbrt(number);

这在 .NET Framework 4.8 中不可用。