`
pupi
  • 浏览: 433635 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

一道java面试题

阅读更多
这是面试的季节。

前几天去面试,碰到一个java题目,要求1000!(1000*999*998...*2*1)的值。
因为很显然,用原始的类型,即使是double,也没有办法容纳这么大的数字。所以当时用了下面的方法:
		double c = 1.0;
		int scale = 0;
		for(int i=1; i<1001; i++) {
			c *= i;
			if(c > 1000000000) {
				c = c/1000000000;
				scale += 9;
			}
		}
		System.out.println("1000! = "+c+"*10("+scale+")");

方法的输出为
1000! = 402.38726007709414*10(2565)

可以看出,小数点的位数有点不够。

回家看了看jdk的api,看到了BigDecimal这个类,嗯,这个类才是处理此类问题的正解,很简单。
		BigDecimal big = new BigDecimal(1);
		for(int i=1; i<1001; i++) {
			big = big.multiply(new BigDecimal(i));
		}
		big.setScale(100);
		System.out.println(big);

方法的输出为:
40238726007709377354370243392300398571937486421071463254379991042993851239862
90205920442084869694048004799886101971960586316668729948085589013238296699445
90997424504087073759918823627727188732519779505950995276120874975462497043601
41827809464649629105639388743788648733711918104582578364784997701247663288983
59557354325131853239584630755574091142624174743493475534286465766116677973966
68820291207379143853719588249808126867838374559731746136085379534524221586593
20192809087829730843139284440328123155861103697680135730421616874760967587134
83120254785893207671691324484262361314125087802080002616831510273418279777047
84635868170164365024153691398281264810213092761244896359928705114964975419909
34222156683257208082133318611681155361583654698404670897560290095053761647584
77284218896796462449451607653534081989013854424879849599533191017233555566021
39450399736280750137837615307127761926849034352625200015888535147331611702103
96817592151090778801939317811419454525722386554146106289218796022383897147608
85062768629671466746975629112340824392081601537808898939645182632436716167621
79168909779911903754031274622289988005195444414282012187361745992642956581746
62830295557029902432415318161721046583203678690611726015878352075151628422554
02651704833042261439742869330616908979684825901254583271682264580665267699586
52682272807075781391858178889652208164348344825993266043367660176999612831860
78838615027946595513115655203609398818061213855860030143569452722420634463179
74605946825731037900840244324384656572450144028218852524709351906209290231364
93273497565513958720559654228749774011413346962715422845862377387538230483865
68897646192738381490014076731044664025989949022222176590433990188601856652648
50617997023561938970178600408118897299183110211712298459016419210688843871218
55646124960798722908519296819372388642614839657382291123125024186649353143970
13742853192664987533721894069428143411852015801412334482801505139969429015348
30776445690990731524332782882698646027898643211390835062170950025973898635542
77196742822248757586765752344220207573630569498825087968928162753848863396909
95982628095612145099487170124451646126037902930912088908694202851064018215439
94571568059418727489980942547421735824010636774045957417851608292301353580818
40096996372524230560855903700624271243416909004153690105933983835777939410970
02775347200000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000

恐怖的数字,呵呵。
分享到:
评论
16 楼 Godlikeme 2007-03-18  
hurricane1026 写道
我倒觉得为什么不自己写一个自己的bigDecimal呢?你如果会小学的乘法竖式就没有理由不会这个吧。招聘要是去考api也真够无聊的。
ps:不好意思,回完了才发现已经被实现了。

恩,我自己写了一个,不过根上面那位的一比就相形见拙了。
另,我比他的复杂,有小数位,但不够简洁。
15 楼 eboge 2007-03-16  
楼上的楼上不厚道
14 楼 抛出异常的爱 2007-03-15  
楼上不厚道
13 楼 Godlikeme 2007-03-15  
非常棒
12 楼 8844.43 2007-03-14  
andershong 写道
Godlikeme 写道
BigDecimal就是string的,表示整数没问题,但是在表示小数上bigdecimal还是有精度限制的。

我觉得string只是一个Cache的作用,大数实现上应该是数组实现的.
这个题要是我答会这样(粗糙写了一下):
public class BigNumber {
	private static int[] ret=new int[3000];
	private static int len=0;
	
	public static void main(String[] args) {
		factorialFun(1000);
		for(int i=len-1;i>=0;i--){
			System.out.print(ret[i]);
		}
	}
	
	private static void factorialFun(int n){
		for(int i=1;i<=n;i++){
			if(i==1){
				ret[0]=1;
				len=1;
			}else{
				for(int j=0;j<len;j++){
					ret[j]=i*ret[j];
				}
				for(int j=0;j<len;j++){
					if(ret[j]>=10){
						if(ret[len-1]>=10){
							len++;
						}
						ret[j+1]+=ret[j]/10;
						ret[j]=ret[j]%10;
					}
				}
			}
		}
	}
}

受教!!
11 楼 andershong 2007-03-14  
Godlikeme 写道
BigDecimal就是string的,表示整数没问题,但是在表示小数上bigdecimal还是有精度限制的。

我觉得string只是一个Cache的作用,大数实现上应该是数组实现的.
这个题要是我答会这样(粗糙写了一下):
public class BigNumber {
	private static int[] ret=new int[3000];
	private static int len=0;
	
	public static void main(String[] args) {
		factorialFun(1000);
		for(int i=len-1;i>=0;i--){
			System.out.print(ret[i]);
		}
	}
	
	private static void factorialFun(int n){
		for(int i=1;i<=n;i++){
			if(i==1){
				ret[0]=1;
				len=1;
			}else{
				for(int j=0;j<len;j++){
					ret[j]=i*ret[j];
				}
				for(int j=0;j<len;j++){
					if(ret[j]>=10){
						if(ret[len-1]>=10){
							len++;
						}
						ret[j+1]+=ret[j]/10;
						ret[j]=ret[j]%10;
					}
				}
			}
		}
	}
}
10 楼 抛出异常的爱 2007-03-14  
Godlikeme 写道
BigDecimal就是string的,表示整数没问题,但是在表示小数上bigdecimal还是有精度限制的。

受教了....
人类智慧是很难超越的....
9 楼 Godlikeme 2007-03-13  
BigDecimal就是string的,表示整数没问题,但是在表示小数上bigdecimal还是有精度限制的。
8 楼 抛出异常的爱 2007-03-13  
andershong 写道
个人觉得他出这题的目的不是考察BigDecimal的用法,
而是用算法解决大数运算的能力.
用string来算?
7 楼 andershong 2007-03-13  
个人觉得他出这题的目的不是考察BigDecimal的用法,
而是用算法解决大数运算的能力.
6 楼 coolwangyu 2007-03-13  
一般跟钱、汇率、税金等有关的需要,其他的没必要
5 楼 ddandyy 2007-03-13  
我们公司所有的项目关于计算的都要求使用BigDecimal
4 楼 pupi 2007-03-12  
也没有那么严格吧,感觉。
3 楼 抛出异常的爱 2007-03-11  
你面视时可以要API么
2 楼 pupi 2007-03-10  
BigInteger也可以的。
1 楼 liuyifan.com 2007-03-10  
那bigInteger呢

相关推荐

Global site tag (gtag.js) - Google Analytics