You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Binet公式计算斐波那契偶数和结果偏差1的问题排查

斐波那契偶数和计算的精度问题分析

你用Binet公式结合斐波那契数列每第三项为偶数的特性计算小于4000000的偶数项和,结果比正确值多1,核心原因就是浮点数精度不足,具体拆解如下:

问题根源

  • float类型的精度局限:float只有6-7位有效数字,你手动赋值的sqrt5、goldenRatio都是近似值,本身就存在误差。随着n增大,Math.pow会把这个误差指数级放大,导致计算出的斐波那契数偏离真实值。比如某个偶数项的计算值刚好比真实值大0.5以上,Math.round就会把它进位成大1的数,累加后总和就多了1。
  • Binet公式的误差积累:公式中Math.pow(reciprocalGoldenRaio, nth)这一项,当n增大时绝对值趋近于0,但float的精度不足以准确表示这个极小值,残留的误差会干扰最终结果的计算,进一步加剧数值偏差。

修正方案

1. 提升浮点数精度

把所有float类型换成double,double有15-17位有效数字,能大幅降低精度误差。同时不要手动输入近似值,直接用计算得到的精确值:

public static final double sqrt5 = Math.sqrt(5);
public static final double goldenRatio = (1 + sqrt5) / 2;
public static final double reciprocalGoldenRatio = (1 - sqrt5) / 2;

2. 优化循环逻辑

原循环for (int i = 0; i < 4_000_000; i += 3)完全没必要,斐波那契数列增长极快,远没到i=400万时数值就会超过400万。改成当计算值超过阈值时直接终止循环:

long sum = 0;
int n = 0;
while (true) {
  long number = binetsFormula(n);
  if (number >= 4_000_000L) {
    break;
  }
  sum += number;
  n += 3;
}

修正后的完整代码

/*
  通过Binet公式和斐波那契数列每第三项为偶数的特性计算
*/

public class Optimised002 {
  public static void main(String[] args) {
    long sum = 0;
    int n = 0;
    while (true) {
      long number = binetsFormula(n);
      if (number >= 4_000_000L) {
        break;
      }
      sum += number;
      n += 3;
    }
    System.out.println(sum);
  }

  public static final double sqrt5 = Math.sqrt(5);
  public static final double goldenRatio = (1 + sqrt5) / 2;
  public static final double reciprocalGoldenRatio = (1 - sqrt5) / 2;

  public static long binetsFormula(int nth) {
    return Math.round((Math.pow(goldenRatio, nth) - Math.pow(reciprocalGoldenRatio, nth)) / sqrt5);
  }
}

内容的提问来源于stack exchange,提问作者nobody

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 15:48:31