java整形变量存不下上兆亿的数字 !?
java中int的取值范围
首先java中的八种基本类型复习一下。int,short,long,double,float,byte,boolean,char
如果你想的是:怎么不写String类型啊?,这个人是不是傻啊?,那么我建议你这个号重开吧。众所周知,String是一个对象类。并不包含在基本类型中。
其中int 数据类型是32位、有符号的以二进制补码表示的整数;
最小值是 -2,147,483,648(-2^31);
最大值是 2,147,483,647(2^31 - 1);
一般地整型变量默认为 int 类型;
由上可得int类型的取值范围 (-231)~(231-1)
取值范围的局限性
正常的变量取值范围大概都在这个区间,但是遇到一些科研数据或者一些脑残的算法题就会超出这个取值范围。比如计算两个星系之前的距离,单位为KM,请给出具体数值。类似的例子还有很多。如 n 的阶乘 n!
本人测试,发现当 n<=14时整形可以显示,当 n >14时,结果会改变或者溢出为负数。
附上本人的测试代码:
import java.util.Scanner;
public class test{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("please input the number:");
int data = in.nextInt();
System.out.println("the result is :"+result(data));
}
public static int result(int m){
if(m == 1)
return 1;
return m*result(m-1);
}
}
截图如下:
看见没这结果就离谱
解决方法与分歧
如果你必须获得20!这个值,你怎么办呢?大部分人可能会选择 long int 类型,或者java提供的大数运算类型BigIntiger,想具体了解的请自行搜索。在这里我主要说一下,用数组存储超大型数字的例子。
其实就是很简单的字符数组类型的乘法运算。伪代码如下:
字符串处理:
输入 (n-1) ! 所组成的字符串 result [ ],和 n
遍历result,一次对单个字符强转换为int类型,并乘以 n,即 result[i] = ((int)result[i] * n )%10 ,temp 存储该值对10的倍数
a[i+1]=a[i+1]+temp
具体代码如下:
/**
*
* @author DELL
*
* n的阶乘
* 对于该值来说,当n位于20以内时,可以用正常的方法来做,可当超出这个范围时会出现溢出值,因此需要用
* 数组的形式来进行运算和存储。
*/
public class Start {
private StringBuilder totalBuilder = new StringBuilder();
public static void main(String[] args) {
Start mStart = new Start();
mStart.result(4);
}
//运用了递归的理念
StringBuilder result(int n) {
if(n==1) {
System.out.println(1);
return totalBuilder.append("1");
}
return plusResult(n, result(n-1).reverse().toString().toCharArray());
}
static StringBuilder plusResult(int n,char[] nums) {
//store the high level single number
char m = '0';
//store the high level tenth number
int middle = 0;
//store the results
int temp=0;
for(int i=0;i<nums.length;i++) {
middle = m-48;
//字符转整形减去ascII码的值
temp = ((nums[i]-48)*n);
//该位数的乘积与进位之和
if(temp+middle>10)
m= (char)(((temp+middle)/10)+48);
else {
m = '0';
}
nums[i]=(char)(((temp+middle)%10)+48);
}
StringBuilder teBuilder = new StringBuilder();
teBuilder.append(String.valueOf(nums));
if(m!='0') {
teBuilder.append(m);
System.out.println(teBuilder.reverse());
}
else {
System.out.println(teBuilder.reverse());
}
return teBuilder;
}
}
总结
在一些常见的大数运算中,用字符串来存储大型数字是一种很常见的思路。其实可以扩展一下,这种方法可以成为一个计算器中加法的部分。甚至只要经过几个部分的修改就可以变成一个完整的计算器。目前我正在实现这个功能,希望过几天可以发出来给大家看看。(ps:人不写个博客真的觉得自己啥都会,可惜一敲代码就没那本事儿了,果然人还是要多学习才能沉淀下来啊。)