【问题标题】:Java's Math.Pow() function returning confusing resultsJava 的 Math.Pow() 函数返回令人困惑的结果
【发布时间】:2011-01-25 16:45:16
【问题描述】:

我正在使用 Math.pow() 函数,并且有以下代码:

double monthlyRate = (0.7d / 12);
int loanLength = 3;

double powerTest = Math.pow(1.00583, 36);
double powerResult = Math.pow((1 + monthlyRate),(loanLength * 12));

当它通过调试器运行时,值变为

powerTest => 1.2327785029794363
powerResult => 7.698552870922063

第一个是正确的。我已经在两条分配线上都进入了 Math.pow 函数。对于功率测试, Math.pow 的参数是 双a => 1.00583 双 b => 36.0

对于 powerResult,它们是 双a => 1.0058333333333333 双 b => 36.0

我知道这是机器执行浮点数学的方式的问题,我只是不确定如何纠正它。我在计算前尝试了以下操作,结果很差:

monthlyRate = Math.round(monthlyRate * 1000) / 1000;

【问题讨论】:

  • 你对 (1+(0.7/12))^(3⋅12) 有什么期望?我在常规计算器中得到 7.6985528709220588862786。
  • 在 Java 上,您应该使用 BigDecimal 来执行货币操作。看看我的回答。

标签: java pow


【解决方案1】:

1 + monthlyRate1.0583...,而不是 1.00583

【讨论】:

    【解决方案2】:

    您的表达式 0.7d/12 = 0.0583,在 powerTest 表达式中您使用的是 0.00583。

    【讨论】:

      【解决方案3】:

      我认为部分问题在于0.7/12 ~ 0.0583331.0583 > 1.00583。我敢打赌,这是您的差异的真正来源,浮点调整与此无关。

      【讨论】:

        【解决方案4】:

        显然,resut(1.23... 和 7.70) 的如此大差异与浮点数的编码方式无关,但不仅仅是你在某处犯了错误 1+0.7/12 = 1.0583 不同于 1.00583 ;-)。

        【讨论】:

          【解决方案5】:
          Math.round(monthlyRate * 1000) / 1000.0;
          

          您使用的是整数除法。

          【讨论】:

          • 忽略这一点,实际问题是额外的零,正如 axtavt 指出的那样。我留下答案,以防 OP 实际上想要执行舍入。
          • 谢谢 Nikita,如果以后要写类似的函数,我会注意的
          【解决方案6】:

          在 Java 上,您可以使用 BigDecimal 执行货币操作,从而得到准确的数字:Sun/Oracle recommended way 用于存储货币数字。

          // I'm using Strings for most accuracy
          
          BigDecimal monthlyRate = new BigDecimal("0.7").divide(new BigDecimal(12));
          int loanLength = 3;
          
          BigDecimal powerTest = new BigDecimal("1.00583").pow(36);
          BigDecimal powerResult = BigDecimal.ONE.add(monthlyRate).pow(loanLength * 12);
          

          【讨论】:

          • 请解释您的反对意见。 OP 正在执行货币操作,他应该使用 BigDecimal。
          【解决方案7】:
          monthlyRate = ((double)Math.round(monthlyRate * 1000)) / 1000;
          

          【讨论】:

            猜你喜欢
            • 2020-08-23
            • 1970-01-01
            • 1970-01-01
            • 2018-07-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多