【问题标题】:How wrong do I use Math.Pow(a,b) function in this C# code?我在这个 C# 代码中使用 Math.Pow(a,b) 函数有多大错误?
【发布时间】:2011-01-18 11:04:50
【问题描述】:

我找不到以下代码有什么问题,因此 MSVC# 编译器将 NAN 存储在“c”中:

double c = Math.Pow(-8d, 1d / 3d);

虽然我认为这一行应该为“c”计算 -2,但编译器将 NAN 存储在“c”中? 我有什么不对吗?

【问题讨论】:

    标签: c# math pow


    【解决方案1】:

    浮点数的幂函数仅针对正基数或整数指数定义。试试

    double c = - Math.Pow(8d, 1d / 3d);
    

    其实1/3不能完全表示为浮点数,需要四舍五入。理论上甚至不存在四舍五入指数的精确真实结果。

    【讨论】:

      【解决方案2】:

      通常,人们不会说 (-8)^(1/3) = -2。

      确实 (-2)^3 = -8,但是负数的幂是一个复杂的问题。

      您可以在Wikipedia 上阅读有关该问题的更多信息:

      对数法和 可以使用有理指数法 将 a^r 定义为 a 的实数 负实数 a 和 an 任意实数 r。确实,呃是 对每个实数 r 都是正数,所以 ln(a) 未定义为实数 对于 a ≤ 0。(另一方面, 负的任意复数幂 数字 a 可以通过选择 a 来定义 a的复对数。)

      简而言之,在数学上很难正确定义 a^r 应该是什么,当 a 为负数时,以免开始处理复数,因此一般人应该避免尝试这样做。

      【讨论】:

        【解决方案3】:

        答案是一个复数:1.0+1.732050807568877i。 .NET 的 Math 类不支持复数。

        【讨论】:

        • @user388360:-2 是一个可能的答案。取决于规范是否被认为是正确的。
        • 我不认为这是一个合理的理由。例如,8^(1/3) 的答案之一等于 -1+i*3^(1/2)。但是当我们使用 c=Math.Pow(8d,1d/3d) 时,我们期望得到 c=2 而对数学类复杂支持能力没有任何希望。我认为主要问题出在 .NET 中计算负数的第 n 个根的算法。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-01-05
        • 1970-01-01
        • 2016-10-27
        • 1970-01-01
        • 2015-12-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多