Fibonacci(N)=Fibonacii(N-1)+Fibonacci(N-2)

其中 Fibonacci(0)=0;Fibonacci(1)=1

用循环或则递归实现Fibonacci算法很简单,这里就不说了,如果要用公式实现的话,需要进行开根号和幂运算,普通的long型号只能精确到小数点之后的16位,这就意味着当N很大的时候由于小数位overflow无法进行精确运算,本人测试当N大于92时候因为数据溢出的原因就与实际结果不一样了,如果小数点后面不是精确16位,而是自己设定的话,那么运算结果会精确到自己的期望值。JAVA为我们提供了BigDecimal这个类,BigDecimal类提供了幂运算,但是没有提供开平方运算,Fibonacci公式中的开平方运算要自己实现。这里主要介绍一下自己是如何实现开平方运算的

  1. private static BigDecimal mysqrt(BigDecimal a, int scale) {
  2.  
  3. BigDecimal x = new BigDecimal(Math.sqrt(a.doubleValue()),
  4. MathContext.DECIMAL64);
  5. if (scale < 17)
  6. return x;
  7.  
  8. BigDecimal b2 = new BigDecimal("2");
  9. for (int tempScale = 16; tempScale < scale; tempScale *= 2) {
  10. // x = x - (x * x - a) / (2 * x);
  11. x = x.subtract(x.multiply(x).subtract(a)
  12. .divide(x.multiply(b2), scale, BigDecimal.ROUND_HALF_EVEN));
  13. }
  14. return x;
  15.  
  16. }

这里用到了牛顿线性迭代算法,如果不明白的话可以在百度搜索。返回的结果是小数点后精确到scale位的数字。

现在把所有代码给出

  1. package com.fujitsu.soft.rad.devsemi.fibonacci3;
  2.  
  3. import java.math.BigDecimal;
  4. import java.math.MathContext;
  5.  
  6. public class Fibonacci {
  7.  
  8. /*
  9. * by l.zhang
  10. */
  11. public static void main(String[] args) {
  12.  
  13. System.out.println(fibonacci(100));
  14.  
  15. }
  16.  
  17. /*
  18. * by l.zhang
  19. */
  20.  
  21. public static String fibonacci(int i) {// 大きい桁表現すればlong 2動作の問題
  22.  
  23. if (i < 0 || i > 1000) {
  24. System.out.println("please input a new number ");
  25. return "-1";
  26. } else if (i == 0) {
  27.  
  28. return "0";
  29. } else if (i == 1) {
  30. return "1";
  31. } else {
  32. return siki(i);
  33.  
  34. }
  35.  
  36. }
  37.  
  38. /*
  39. * 公式で計算 i>=2 by l.zhang
  40. */
  41. private static String siki(int i) {
  42.  
  43. BigDecimal temp1 = mysqrt(new BigDecimal("5.0"), 100);// Math.pow(5.0,
  44. // 0.5)
  45. BigDecimal temp2 = temp1.divide(new BigDecimal("5.0"));// Math.pow(5.0,
  46. // 0.5) / 5.0;
  47. BigDecimal temp3 = new BigDecimal("1.0");
  48. BigDecimal temp4 = temp3.add(temp1);// (1 + Math.pow(5.0, 0.5))
  49. BigDecimal temp5 = temp3.subtract(temp1);// (1 - Math.pow(5.0, 0.5))
  50. BigDecimal temp6 = temp4.divide(new BigDecimal("2.0"));// (1 +
  51. // Math.pow(5.0,
  52. // 0.5)) / 2.0
  53. BigDecimal temp7 = temp5.divide(new BigDecimal("2.0"));// (1 -
  54. // Math.pow(5.0,
  55. // 0.5)) / 2.0
  56. BigDecimal temp8 = temp6.pow(i, new MathContext(100));// Mypow(temp6,
  57. // i);//
  58. // Math.pow((1 +
  59. // Math.pow(5.0, 0.5))
  60. // / 2.0, i)
  61.  
  62. BigDecimal temp9 = temp7.pow(i, new MathContext(100));// Mypow(temp7,
  63. // i);//
  64. // Math.pow((1 -
  65. // Math.pow(5.0, 0.5))
  66. // / 2.0, i);
  67. // double temp2 = Math.pow((1 + Math.pow(5.0, 0.5)) / 2.0, i);
  68. // double temp3 = Math.pow((1 - Math.pow(5.0, 0.5)) / 2.0, i);
  69. BigDecimal temp10 = temp8.subtract(temp9);
  70. BigDecimal result = temp2.multiply(temp10);
  71.  
  72. String str_res = result.toString();
  73. System.out.println(str_res);
  74. int index = str_res.indexOf(".", 0);
  75.  
  76. return str_res.substring(0, index);
  77. // (temp1 * (temp2 - temp3));
  78. }
  79.  
  80. private static BigDecimal mysqrt(BigDecimal a, int scale) {
  81.  
  82. BigDecimal x = new BigDecimal(Math.sqrt(a.doubleValue()),
  83. MathContext.DECIMAL64);
  84. if (scale < 17)
  85. return x;
  86.  
  87. BigDecimal b2 = new BigDecimal("2");
  88. for (int tempScale = 16; tempScale < scale; tempScale *= 2) {
  89. // x = x - (x * x - a) / (2 * x);
  90. x = x.subtract(x.multiply(x).subtract(a)
  91. .divide(x.multiply(b2), scale, BigDecimal.ROUND_HALF_EVEN));
  92. }
  93. return x;
  94.  
  95. }
  96.  
  97. }

用BigDecimal类实现Fibonacci算法的更多相关文章

  1. 算法笔记--java的BigInteger类及BigDecimal类

    引包:import java.math.*; BigInteger类: 可以使用构造方法:public BigInteger(String val),或者valueOf(int)函数,如: BigIn ...

  2. java中小数的处理:高精度运算用bigDecimal类,精度保留方法,即舍入方式的指定

    一. 计算机的小数计算一定范围内精确,超过范围只能取近似值: 计算机存储的浮点数受存储bit位数影响,只能保证一定范围内精准,超过bit范围的只能取近似值. java中各类型的精度范围参见:http: ...

  3. 用C# BigInteger实现的BigDecimal类,终于可以直接做四则运算了。

    https://code.google.com/p/dotnet-big-decimal/ 这是个BigDecimal类的开源项目,支持Operators +, - and *. 俺给改了改,加上了除 ...

  4. java基础-BigDecimal类常用方法介绍

    java基础-BigDecimal类常用方法介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.BigDecimal类概述 我们知道浮点数的计算结果是未知的.原因是计算机二进制 ...

  5. JAVA集合类简要笔记 - 内部类 包装类 Object类 String类 BigDecimal类 system类

    常用类 内部类 成员内部类.静态内部类.局部内部类.匿名内部类 概念:在一个类的内部再定义一个完整的类 特点: 编译之后可生成独立的字节码文件 内部类可直接访问外部类私有成员,而不破坏封装 可为外部类 ...

  6. Java:利用BigDecimal类巧妙处理Double类型精度丢失

    目录 本篇要点 经典问题:浮点数精度丢失 十进制整数如何转化为二进制整数? 十进制小数如何转化为二进制数? 如何用BigDecimal解决double精度问题? new BigDecimal(doub ...

  7. BigDecimal类

    如果需要精确的计算结果,则必须使用BigDecimal类,而且使用BigDecimal类也可以进行大数的操作. //========================================== ...

  8. Java大数处理类:BigInteger类和BigDecimal类

    当我们要处理非常大的数据时,平常用的数据类型已不足以表示,在Java中有两个类BigInteger和BigDecimal分别表示大整数类和大浮点数类,这两个类在理论上只要计算机内存足够大就能够表示无线 ...

  9. BIgInteger类和BigDecimal类的理解

    第一部分: 这两个类位于java.math包内,要使用它们必须在类前面引用该包:import java.math.BigInteger;和import java.math.BigDecimal; Bi ...

随机推荐

  1. 更改git bash默认的路径

    更改git bash默认的路径   在打开git bash时,每次都是在C:\Uer路径下,每次都需要先用cd命令转换到自己需要工作的路径(cd  /f/dss).修改打开git bash 时的默认的 ...

  2. 第一部分实现功能:使用一个TabControl和一个Memo和TDictionary类实现文本临时存储

    效果图: 一期功能概要: a.双击tab关闭tab,双击tab右边空白添加tab(标题为以hhnnsszzz的时间格式命名) b.切换tab将数据存入dictionary,key为标题,value为m ...

  3. SDC(6)–I/O约束

    应理解为仅限于内部的约束.即从输入Pin到寄存器D口,以及从寄存器Q口到输出Pin. 例如: 约束如下: 注意set_output_delay的计算

  4. Uva 654 Ratio

    题意: 给两个数, n, m 构造一个序列, 分母从1 ~ m, 并且j / i越来越接近n/m. 思路: 如果存在 j / i 趋近于 n / m 那么则有 j = n * i / m + 0.5( ...

  5. Maven仓库详解

    转载自:Maven入门指南④:仓库   1 . 仓库简介 没有 Maven 时,项目用到的 .jar 文件通常需要拷贝到 /lib 目录,项目多了,拷贝的文件副本就多了,占用磁盘空间,且难于管理.Ma ...

  6. [转载]初学C#之list

    C# List<T>用法 所属命名空间:System.Collections.Generic public class List<T> : IList<T>, IC ...

  7. SQL中Case的使用方法(下篇)(转)

    接上篇 四,根据条件有选择的UPDATE. 例,有如下更新条件 工资5000以上的职员,工资减少10% 工资在2000到4600之间的职员,工资增加15% 很容易考虑的是选择执行两次UPDATE语句, ...

  8. Eclipse 安装Activiti 插件失败解决方法

    遇到的错误为:1.4.0' but it could not be found等.

  9. 在Android手机上安装linux系统

    在anroid手机中安装fedora系统.记住不只是教你安装fedora系统. 需要的备注与软件 1.一个已经root的Android手机,记住是root后的,root后的,root后的.(重要的事情 ...

  10. 6个常见的 PHP 安全性攻击

    了解常见的PHP应用程序安全威胁,可以确保你的PHP应用程序不受攻击.因此,本文将列出 6个常见的 PHP 安全性攻击,欢迎大家来阅读和学习. 1.SQL注入 SQL注入是一种恶意攻击,用户利用在表单 ...