用BigDecimal类实现Fibonacci算法
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公式中的开平方运算要自己实现。这里主要介绍一下自己是如何实现开平方运算的
- private static BigDecimal mysqrt(BigDecimal a, int scale) {
- BigDecimal x = new BigDecimal(Math.sqrt(a.doubleValue()),
- MathContext.DECIMAL64);
- if (scale < 17)
- return x;
- BigDecimal b2 = new BigDecimal("2");
- for (int tempScale = 16; tempScale < scale; tempScale *= 2) {
- // x = x - (x * x - a) / (2 * x);
- x = x.subtract(x.multiply(x).subtract(a)
- .divide(x.multiply(b2), scale, BigDecimal.ROUND_HALF_EVEN));
- }
- return x;
- }
这里用到了牛顿线性迭代算法,如果不明白的话可以在百度搜索。返回的结果是小数点后精确到scale位的数字。
现在把所有代码给出
- package com.fujitsu.soft.rad.devsemi.fibonacci3;
- import java.math.BigDecimal;
- import java.math.MathContext;
- public class Fibonacci {
- /*
- * by l.zhang
- */
- public static void main(String[] args) {
- System.out.println(fibonacci(100));
- }
- /*
- * by l.zhang
- */
- public static String fibonacci(int i) {// 大きい桁表現すればlong 2動作の問題
- if (i < 0 || i > 1000) {
- System.out.println("please input a new number ");
- return "-1";
- } else if (i == 0) {
- return "0";
- } else if (i == 1) {
- return "1";
- } else {
- return siki(i);
- }
- }
- /*
- * 公式で計算 i>=2 by l.zhang
- */
- private static String siki(int i) {
- BigDecimal temp1 = mysqrt(new BigDecimal("5.0"), 100);// Math.pow(5.0,
- // 0.5)
- BigDecimal temp2 = temp1.divide(new BigDecimal("5.0"));// Math.pow(5.0,
- // 0.5) / 5.0;
- BigDecimal temp3 = new BigDecimal("1.0");
- BigDecimal temp4 = temp3.add(temp1);// (1 + Math.pow(5.0, 0.5))
- BigDecimal temp5 = temp3.subtract(temp1);// (1 - Math.pow(5.0, 0.5))
- BigDecimal temp6 = temp4.divide(new BigDecimal("2.0"));// (1 +
- // Math.pow(5.0,
- // 0.5)) / 2.0
- BigDecimal temp7 = temp5.divide(new BigDecimal("2.0"));// (1 -
- // Math.pow(5.0,
- // 0.5)) / 2.0
- BigDecimal temp8 = temp6.pow(i, new MathContext(100));// Mypow(temp6,
- // i);//
- // Math.pow((1 +
- // Math.pow(5.0, 0.5))
- // / 2.0, i)
- BigDecimal temp9 = temp7.pow(i, new MathContext(100));// Mypow(temp7,
- // i);//
- // Math.pow((1 -
- // Math.pow(5.0, 0.5))
- // / 2.0, i);
- // double temp2 = Math.pow((1 + Math.pow(5.0, 0.5)) / 2.0, i);
- // double temp3 = Math.pow((1 - Math.pow(5.0, 0.5)) / 2.0, i);
- BigDecimal temp10 = temp8.subtract(temp9);
- BigDecimal result = temp2.multiply(temp10);
- String str_res = result.toString();
- System.out.println(str_res);
- int index = str_res.indexOf(".", 0);
- return str_res.substring(0, index);
- // (temp1 * (temp2 - temp3));
- }
- private static BigDecimal mysqrt(BigDecimal a, int scale) {
- BigDecimal x = new BigDecimal(Math.sqrt(a.doubleValue()),
- MathContext.DECIMAL64);
- if (scale < 17)
- return x;
- BigDecimal b2 = new BigDecimal("2");
- for (int tempScale = 16; tempScale < scale; tempScale *= 2) {
- // x = x - (x * x - a) / (2 * x);
- x = x.subtract(x.multiply(x).subtract(a)
- .divide(x.multiply(b2), scale, BigDecimal.ROUND_HALF_EVEN));
- }
- return x;
- }
- }
用BigDecimal类实现Fibonacci算法的更多相关文章
- 算法笔记--java的BigInteger类及BigDecimal类
引包:import java.math.*; BigInteger类: 可以使用构造方法:public BigInteger(String val),或者valueOf(int)函数,如: BigIn ...
- java中小数的处理:高精度运算用bigDecimal类,精度保留方法,即舍入方式的指定
一. 计算机的小数计算一定范围内精确,超过范围只能取近似值: 计算机存储的浮点数受存储bit位数影响,只能保证一定范围内精准,超过bit范围的只能取近似值. java中各类型的精度范围参见:http: ...
- 用C# BigInteger实现的BigDecimal类,终于可以直接做四则运算了。
https://code.google.com/p/dotnet-big-decimal/ 这是个BigDecimal类的开源项目,支持Operators +, - and *. 俺给改了改,加上了除 ...
- java基础-BigDecimal类常用方法介绍
java基础-BigDecimal类常用方法介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.BigDecimal类概述 我们知道浮点数的计算结果是未知的.原因是计算机二进制 ...
- JAVA集合类简要笔记 - 内部类 包装类 Object类 String类 BigDecimal类 system类
常用类 内部类 成员内部类.静态内部类.局部内部类.匿名内部类 概念:在一个类的内部再定义一个完整的类 特点: 编译之后可生成独立的字节码文件 内部类可直接访问外部类私有成员,而不破坏封装 可为外部类 ...
- Java:利用BigDecimal类巧妙处理Double类型精度丢失
目录 本篇要点 经典问题:浮点数精度丢失 十进制整数如何转化为二进制整数? 十进制小数如何转化为二进制数? 如何用BigDecimal解决double精度问题? new BigDecimal(doub ...
- BigDecimal类
如果需要精确的计算结果,则必须使用BigDecimal类,而且使用BigDecimal类也可以进行大数的操作. //========================================== ...
- Java大数处理类:BigInteger类和BigDecimal类
当我们要处理非常大的数据时,平常用的数据类型已不足以表示,在Java中有两个类BigInteger和BigDecimal分别表示大整数类和大浮点数类,这两个类在理论上只要计算机内存足够大就能够表示无线 ...
- BIgInteger类和BigDecimal类的理解
第一部分: 这两个类位于java.math包内,要使用它们必须在类前面引用该包:import java.math.BigInteger;和import java.math.BigDecimal; Bi ...
随机推荐
- 更改git bash默认的路径
更改git bash默认的路径 在打开git bash时,每次都是在C:\Uer路径下,每次都需要先用cd命令转换到自己需要工作的路径(cd /f/dss).修改打开git bash 时的默认的 ...
- 第一部分实现功能:使用一个TabControl和一个Memo和TDictionary类实现文本临时存储
效果图: 一期功能概要: a.双击tab关闭tab,双击tab右边空白添加tab(标题为以hhnnsszzz的时间格式命名) b.切换tab将数据存入dictionary,key为标题,value为m ...
- SDC(6)–I/O约束
应理解为仅限于内部的约束.即从输入Pin到寄存器D口,以及从寄存器Q口到输出Pin. 例如: 约束如下: 注意set_output_delay的计算
- Uva 654 Ratio
题意: 给两个数, n, m 构造一个序列, 分母从1 ~ m, 并且j / i越来越接近n/m. 思路: 如果存在 j / i 趋近于 n / m 那么则有 j = n * i / m + 0.5( ...
- Maven仓库详解
转载自:Maven入门指南④:仓库 1 . 仓库简介 没有 Maven 时,项目用到的 .jar 文件通常需要拷贝到 /lib 目录,项目多了,拷贝的文件副本就多了,占用磁盘空间,且难于管理.Ma ...
- [转载]初学C#之list
C# List<T>用法 所属命名空间:System.Collections.Generic public class List<T> : IList<T>, IC ...
- SQL中Case的使用方法(下篇)(转)
接上篇 四,根据条件有选择的UPDATE. 例,有如下更新条件 工资5000以上的职员,工资减少10% 工资在2000到4600之间的职员,工资增加15% 很容易考虑的是选择执行两次UPDATE语句, ...
- Eclipse 安装Activiti 插件失败解决方法
遇到的错误为:1.4.0' but it could not be found等.
- 在Android手机上安装linux系统
在anroid手机中安装fedora系统.记住不只是教你安装fedora系统. 需要的备注与软件 1.一个已经root的Android手机,记住是root后的,root后的,root后的.(重要的事情 ...
- 6个常见的 PHP 安全性攻击
了解常见的PHP应用程序安全威胁,可以确保你的PHP应用程序不受攻击.因此,本文将列出 6个常见的 PHP 安全性攻击,欢迎大家来阅读和学习. 1.SQL注入 SQL注入是一种恶意攻击,用户利用在表单 ...