使用BigDecimal计算第n项斐波那契数时触发NumberFormatException求助
解决BigDecimal计算大斐波那契数时的NumberFormatException问题
嘿,这个问题我之前踩过坑!咱们先拆解下报错根源:你遇到的NumberFormatException,本质是创建BigDecimal时传入了无法被解析为有效数字的内容。结合堆栈里的BigDecimal.valueOf调用来看,大概率是你的代码里用了基本类型(比如double或long)中转斐波那契的中间值,等数值变大超出基本类型的范围/精度后,再转BigDecimal就触发错误了。
举个典型的错误写法例子:
// 错误:用double存中间值,大数值下会精度丢失甚至变成科学计数法 BigDecimal a = new BigDecimal("1000000000000000000"); BigDecimal b = new BigDecimal("2000000000000000000"); double temp = a.doubleValue() + b.doubleValue(); BigDecimal next = BigDecimal.valueOf(temp); // 这里会直接报错!
当数值大到double无法精确表示时,temp会变成类似3E18的科学计数法格式,甚至直接溢出为无穷大,这时候BigDecimal.valueOf(double)底层无法把这种非标准整数格式转成BigDecimal,自然就抛出异常了。
正确的解决方案:全程用BigDecimal做运算
斐波那契的计算应该从始至终基于BigDecimal的方法,完全避免基本类型中转。比如这样实现:
public class Fibonacci { private BigDecimal prevPrev = BigDecimal.ZERO; private BigDecimal prev = BigDecimal.ONE; // 获取下一个斐波那契数 public BigDecimal next() { BigDecimal current = prev.add(prevPrev); prevPrev = prev; prev = current; return current; } // 获取第n项斐波那契数(n从1开始计数) public BigDecimal getNth(int n) { if (n == 1 || n == 2) return BigDecimal.ONE; for (int i = 3; i <= n; i++) { next(); } return prev; } }
这个写法全程用BigDecimal.add()做加法,没有精度损失或类型转换的问题,就算计算到第10000项这种超大斐波那契数也能正常工作。
额外排查小提示
如果你非要用基本类型中转,一定要注意:
- 别用
double,改用long(但long也有上限,大概到第90项左右就会溢出) - 一旦数值接近
Long.MAX_VALUE,立刻切换到BigDecimal运算
不过最稳妥的还是全程用BigDecimal,毕竟斐波那契数增长速度极快,基本类型撑不了几轮就会失效。
内容的提问来源于stack exchange,提问作者Jlan
相关产品推荐
相关产品推荐

