【问题标题】:Is there any reason to use Math.pow() with literals rather than the result itself?是否有任何理由将 Math.pow() 与文字一起使用而不是结果本身?
【发布时间】:2016-07-27 15:39:22
【问题描述】:

我目前正在查看现有代码。已经编写了许多方法来对现有公式进行建模。我偶然发现了几十个代码实例,例如 Math.pow(10.0D, 3.0D)Math.pow(300.0D, 2.0D) 以及 1.5D * 1000.0D 之类的代码。

现在,在我继续用它们各自的结果替换所有这些之前(1000d90000d1500d 对于上面的示例),我想弄清楚是否有任何充分的理由继续使用原始符号?

我想到的唯一一件事就是保持代码与建模公式的相似性。还有其他我看不到的原因吗?

【问题讨论】:

    标签: java formula


    【解决方案1】:

    本质上都是关于可读性的。在处理时间时,您会更常见地看到这种代码样式,例如:

    Thread.sleep(5 * 60 * 1000);
    

    这种风格让线程休眠 5 分钟更加明显。在处理数学公式时,通常会保持公式的每个值不变,因此很明显正在使用什么公式以及正确使用它。

    【讨论】:

    • 对,所以这似乎是唯一的原因。这就是我想知道的 - 谢谢!
    【解决方案2】:

    为了可读性,程序员喜欢把事情写下来:例如,知道正常一天有 86400 秒确实属于参加酒吧测验的人,而不是程序员。

    但话虽如此,我倾向于为此使用Math.pow

    主要原因是它可能不是编译时可评估的常量表达式,尽管可能取决于编译器。

    您可能会发现 pow(x, y) 被实现为 exp(y log x):由于浮点 double 只能精确到大约15 位有效数字。

    (当前 JLS 仅指定一个 Math.pow 函数,该函数接受两个 double 参数。如果您要使用整数文字,那么编译器会在调用函数之前自动将它们转换为 double 类型。看起来作者使用double 字面量来防止将来引入Math.pow 重载的可能性。)

    在您的特定情况下,我会考虑将Math.pow(300.0D, 2.0D) 替换为300.0 * 300.0,将Math.pow(10.0D, 3.0D) 替换为10.0 * 10.0 * 10.0。但请检查这些值是否与原始值相同;并仔细调查任何差异的影响。

    【讨论】:

    • 感谢您的建议。我想知道浮点精度在这里是否相关;尽管从您的回答看来,宁可防止此类问题,但 Math.pow() 的使用更有可能引入它们(如果有的话)。
    • 确实Math.pow 可能会给你带来麻烦,但请注意浮点整数的算术精确到2的53次方。
    【解决方案3】:

    它可以更轻松地验证公式是否已正确转换为代码。还要考虑是否应该将其中一些数字文字替换为命名常量以进一步提高可读性。在不知道上下文的情况下,看起来很多"magic numbers".

    【讨论】:

    • 在这里使用一些命名常量似乎确实是个好主意。我将尝试了解公式的来源,尽可能替换文字。
    猜你喜欢
    • 2010-12-31
    • 2011-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-01
    • 1970-01-01
    • 2018-10-20
    相关资源
    最近更新 更多