高精度运算,是指参与运算的数(加数,减数,因子……)范围大大超出了标准数据类型(整型,实型)能表示的范围的运算。例如,求两个200位的数的和。
整型数据:-32768 — 32767
长整型:-2147483648 — 2147483647
单精度:6位精确度,±(3.4e-38— 3.4e+38)
双精度:17位精确度,±(1.7e-308— 1.7e+308)
解决思想:
1、用数组存储高精度数据,由低到高或由高到低;
2、每位数据或每几位数据占一个数组元素空间;
3、数组可以是整型或字符类型。
例:编程求当n<=100时,n!的准确值。
算法思想:
(1) 累乘因子i取值范围为:1<=i<=n。
(2) 用数组ab存储计算结果,每个数组元素存储6位数据,则数组长度为:m=n*log10n/6 (1<=j<=m) (对数组长度的粗略估计)
(3) 用整数b暂存每个元素乘以i所得到的结果
(4) 用c表示进位,初值c=0
(5) b = ab[j]*i+c; ab[j] = b % 106; d = b/106;
(6) 循环第5步,直到数组ab的所有元素都累乘完毕
(7) 循环第5、6步,直到i取值为n
核心代码如下:
public void factorial (int n) { // n为要求阶乘的数 long b, c=0; int r=0; // r为运算结果存在数组中的真实长度 int m = (int) (Math.log10(n)*n/6) + 2; long[] ab = new long[256]; ab[0] = 1; for (int i=1; i<=m; ++i) { ab[i] = 0; } for (int j=1; j<=n; ++j) { for (int i=0; i<=m; ++i) { b = ab[i]*j + c; ab[i] = b%1000000; c = b/1000000; } } for (int i=m; i>0; --i) { // 求出r的值 if (ab[i] == 0) { continue; } else { r = i; break; } } System.out.PRintln(n + "!="); System.out.print(" " + ab[r] + " "); for (int k=1,i=r-1; i>=0; --i) { // 使输出的每位数组元素都为6位数 if (ab[i]>99999) { System.out.print(ab[i] + " "); } else if (ab[i]>9999) { System.out.print("0" + ab[i] + " "); } else if (ab[i]>999) { System.out.print("00" + ab[i] + " "); } else if (ab[i]>99) { System.out.print("000" + ab[i] + " "); } else if (ab[i]>9) { System.out.print("0000" + ab[i] + " "); } else { System.out.print("00000" + ab[i] + " "); } ++k; if (k%5 == 0) { // 每5个元素一组,分行显示 System.out.println(); } } } 运行结果:注:输出时,首先求出运算结果存储在数组中的准确位数r,然后输出最高位数据,在输出其它存储单元的数据时要特别注意,如若计算结果为123000001,ab[1]中存储的是123,而ab[0]中存储的不是000001,而是1。所以在输出时,通过条件语句保证输出的正确性。
新闻热点
疑难解答