A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

李孝志

中级黑马

  • 黑马币:39

  • 帖子:94

  • 精华:0

       前几天与我同学说起兔子问题(斐波那契数列),他问我第10000个月的兔子数量是多少?然后我就用JAVA开始算。      
       首先用int类型方法
[Java] 纯文本查看 复制代码
public class Tuzi1 {
        public static void main(String[] args) {
                int month = 46;   
                long start = System.currentTimeMillis();                                                                                                                                        
                System.out.println("第"+month+"个月兔子总数为"+fun(month));
                long end = System.currentTimeMillis();
                System.out.println("程序运行时间" + (end-start) + "毫秒");
        }
        private static int fun(int n){
                if(n==1 || n==2)
                   return 1;
                else
                   return fun(n-1)+fun(n-2);
        }
}


但是int长度不够。
当month=46是正数1836311903   month=47是兔子的总数量为-1323752223;表示int数据类型(-2147483648~2147483647)范围越界。第47个月的数量是2971215073;
     然后换long类型,这时又出了一个新问题,在程序中用的是fun()方法,使用了递归,当month>50时,程序运行时间变长,所以把代码改为以下:
[AppleScript] 纯文本查看 复制代码
public class Tuzi2 {
        public static void main(String[] args) {
                long start = System.currentTimeMillis();
                long month=1406;  
                long i1=1;//第一个月兔子为一对
                long i2=1;//第二个月兔子为一对
                long i=0;//代表前一个月兔子的对数
                long sum=0; //兔子的总数
                for(long j=3;j<=month;j++){
                        i=i2;//当J=3时,前一个月即为第二个月,故将i2的值给i
                        i2=i+i1;
                        i1=i;
                        sum=sum+i2+2;
                }
                System.out.println("兔子的总数量为"+sum*2);
                long end = System.currentTimeMillis();
                System.out.println(end-start);
        }
}

但是long类型只能计算到month=88(兔子数量5760134388741632578),超过88,又超范围了,改为double类型,但是double
有一个缺点,大的数字用幂表示,只能精确到小数点后面16位,即使是这样也只能计算到month=1406(兔子数量1.6074684786574634E294)。
        这时我一脸蒙逼的样子,没有类型可用了,这时还没网,用手机搜了一下,找到了BigInteger。
BigInteger介绍:不可变的任意精度的整数。所有操作中,都以二进制补码形式表示 BigInteger(如 Java 的基本整数类型)。
        BigInteger 提供所有 Java 的基本整数操作符的对应物,并提供 java.lang.Math 的所有相关方法。
        另外,BigInteger 还提供以下运算:模算术、GCD 计算、质数测试、素数生成、位操作以及一些其他操作。
1.BigInteger属于java.math.BigInteger,包,因此在每次使用前都要导包。使用时不要忘记导包。
2.其构造方法有很多,但现在我用到的是时:
        1).加法: BigInteger add(BigInteger val)
                返回其值为 (this + val) 的 BigInteger
        2).常量:BigInteger.ONE,常量1.
        3).数组:BigInteger[];
3.另外说明BigInteger的数学运算。
        减法:subtract(BigInteger val)返回其值为 (this - val) 的 BigInteger。
        乘法:multiply(BigInteger val)返回其值为 (this * val) 的 BigInteger。
        除法:divide(BigInteger val)返回其值为 (this / val) 的 BigInteger。
        取模:BigInteger remainder(BigInteger val)返回其值为 (this % val) 的 BigInteger。
        注意:其内容进行数学运算时不能直接使用数学运算符进行运算,必须使用其内部方法。
        而且其操作数也必须为BigInteger型。如:two.add(2)就是一种错误的操作,因为2没有变为BigInteger型。

新代码
[Java] 纯文本查看 复制代码
import java.math.BigInteger;
public class Tuzi3 {        
        public static void main(String[] args) {
                long start=System.currentTimeMillis();
                //创建数组
                        int month=1407;   
                BigInteger[] integers = new BigInteger[month];
                //初始化前两个数字
                integers[0] = BigInteger.ONE;
                integers[1] = BigInteger.ONE;
                for (int i = 2; i < month; i++) 
                    integers = integers[i - 1].add(integers[i - 2]);
                //打印数组
                BigInteger sum =integers[0];
                for (int i = 0; i < integers.length; i++) 
                        sum =integers;               
                System.out.println("第"+ month +"个月兔子数量:" + sum);
                long end=System.currentTimeMillis();
                System.out.println("程序耗时 "+(end-start)+" 毫秒");
        }
}


使用BigInteger,不但能计算出month=10000(用时22毫秒),就是month=20000(用时65毫秒)也可以,因为数据太长,就不写了。

7 个回复

倒序浏览
可以的,很强势
回复 使用道具 举报
BigInteger精度比较高,金融什么的用的比较多
回复 使用道具 举报
向学霸致敬!!!!
回复 使用道具 举报
嗯,想你学习
回复 使用道具 举报
自从知道这道题,觉得养兔子比程序员赚钱
回复 使用道具 举报
又学到了新知识,
回复 使用道具 举报
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马