JAVA高精度数值运算方法,小数点后保留位数,结合相关例题进行介绍!

      int数据类型的位数为16位,short int数据类型的位数为16位,而long int的位数为32位。其余常用数据类型的位数也相当有限。在实际应用中,需要对更大或者更小的数进行运算和处理。Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。

一、Java 中 BigDecimal 类的使用方法

     1、BigDecimal类经常用到的构造方法:

                   1.BigDecimal(int)创建一个具有参数所指定整数值的对象。   例如:BigDecimal sum = new BigDecimal(1);

             2.BigDecimal(double)创建一个具有参数所指定双精度值的对象。   例如:BigDecimal sum = new BigDecimal(2.54);

 

      2、BigDecimal类的常用运算方法:
     由于BigDecimal所创建的是对象,我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。
      1. add(BigDecimal)BigDecimal对象中的值相加,然后返回这个对象。
      2. subtract(BigDecimal)BigDecimal对象中的值相减,然后返回这个对象。
      3. multiply(BigDecimal)BigDecimal对象中的值相乘,然后返回这个对象。
      4. divide(BigDecimal)BigDecimal对象中的值相除,然后返回这个对象。
  用一些例子进行理解:
      //创建BigDecimal对象
        BigDecimal bigNumber = new BigDecimal("89.1234567890123456789");
        BigDecimal bigRate = new BigDecimal(1000);
        BigDecimal bigResult = new BigDecimal(); //对象bigResult的值为0.0
      //对bigNumber的值乘以1000,结果 赋予bigResult
        bigResult = bigNumber.multiply(bigRate);
        System.out.println(bigResult.toString());
      //或者System.out.println(bigResult);
      //显示结果:89123.4567890123456789000
二、BigDecimal和格式化
    由于NumberFormat类的format()方法可以使用BigDecimal对象作为其参数,可以利用BigDecimal对超出16位有效数字的货币值,百分值,以及一般数值进行格式化控制。下面给出代码实现java的舍小数取整、四舍五入取整,四舍五入保留几位小数、凑整取上限的操作:
import java.math.BigDecimal;
public class A {      
			public static void main(String[] args)
			{
				double i = 3.856; 
			       // 舍掉小数取整 
			       System.out.println("舍掉小数取整:Math.floor(3.856)=" + (int) Math.floor(i)); 
			       // 四舍五入取整 
			       System.out.println("四舍五入取整:(3.856)=" 
			       + new BigDecimal(i).setScale(0, BigDecimal.ROUND_HALF_UP)); 
			       // 四舍五入保留两位小数 
			      System.out.println("四舍五入取整:(3.856)=" 
			       + new BigDecimal(i).setScale(2, BigDecimal.ROUND_HALF_UP)); 
			       // 凑整,取上限 
			       System.out.println("凑整:Math.ceil(3.856)=" + (int) Math.ceil(i)); 
					  
		        }
}

在上面代码中:
      1.使用Math.floor(i);方法实现舍掉小数取整的操作,其中形参i就是要进行操作的数。(与BigDecimal类没什么关系)
      2.使用BigDecimal(i).setScale(0, BigDecimal.ROUND_HALF_UP));方法实现四舍五入的操作,其中i为要操作的数,setScale();方法中的“0”,代表小数点后不保留有效数字。以此类推,小数点后保留两位有效数字则为:"BigDecimal(i).setScale(2, BigDecimal.ROUND_HALF_UP));"。
      3.使用Math.ceil(i)方法实现凑整去上限。

三、蓝桥杯以及ACM有关高精度计算的题解法介绍

1.问题描述
  输入一个正整数n,输出n!的值。
  其中n!=1*2*3*…*n。
算法描述
  n!可能很大,而计算机能表示的整数范围有限,需要使用高精度计算的方法。使用一个数组A来表示一个大整数a,A[0]表示a的个位,A[1]表示a的十位,依次类推。
  将a乘以一个整数k变为将数组A的每一个元素都乘以k,请注意处理相应的进位。
  首先将a设为1,然后乘2,乘3,当乘到n时,即得到了n!的值。
输入格式
  输入包含一个正整数n,n<=1000。
输出格式
  输出n!的准确值。
样例输入
10
样例输出
3628800

 

import java.math.BigDecimal;
import java.util.Scanner;
/*输入一个正整数n,输出n!的值。
  其中n!=1*2*3*…*n。*/
public class GaoJingDuJieCheng {
	public static void main(String[] args) {
		BigDecimal sum = new BigDecimal(1);
		BigDecimal temp1 = new BigDecimal(1);
		BigDecimal temp2 = new BigDecimal(1);
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		if(n == 1)
		{
			System.out.println("1");
		}
		else{
		for(int i = 0; i <n-1; i++)
		{
			sum = sum.multiply(temp1.add(temp2));
			temp1 = temp1.add(temp2);
		}
		System.out.println(sum);
		}
	}
}

结合上文BigDecimal类的使用方法进行理解。就不做详细的解析。

2.问题描述

输入两个整数a和b,输出这两个整数的和。a和b都不超过100位。

算法描述
  由于a和b都比较大,所以不能直接使用语言中的标准数据类型来存储。对于这种问题,一般使用数组来处理。
  定义一个数组A,A[0]用于存储a的个位,A[1]用于存储a的十位,依此类推。同样可以用一个数组B来存储b。
  计算c = a + b的时候,首先将A[0]与B[0]相加,如果有进位产生,则把进位(即和的十位数)存入r,把和的个位数存入C[0],即C[0]等于(A[0]+B[0])%10。然后计算A[1]与B[1]相加,这时还应将低位进上来的值r也加起来,即C[1]应该是A[1]、B[1]和r三个数的和.如果又有进位产生,则仍可将新的进位存入到r中,和的个位存到C[1]中。依此类推,即可求出C的所有位。
  最后将C输出即可。
输入格式
  输入包括两行,第一行为一个非负整数a,第二行为一个非负整数b。两个整数都不超过100位,两数的最高位都不是0。
输出格式
  输出一行,表示a + b的值。
样例输入
20100122201001221234567890
2010012220100122
样例输出
20100122203011233454668012

下面的代码利用BigDecimal类完成:

 

import java.math.BigDecimal;
import java.util.Scanner;
public class GaoJingDuQiuHe {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		BigDecimal temp1 = sc.nextBigDecimal();
		BigDecimal temp2 = sc.nextBigDecimal();
		sc.close();
		System.out.println(temp1.add(temp2)); 
	}
}

 

3.问题描述

对数值很大、精度很高的数进行高精度计算是一类十分常见的问题。比如,对国债进行计算就是属于这类问题。

现在要你解决的问题是:对一个实数R( 0.0 < R < 99.999 ),要求写程序精确计算 R 的 n 次方(Rn),其中n 是整数并且 0 < n <= 25。
Input

T输入包括多组 R 和 n。 R 的值占第 1 到第 6 列,n 的值占第 8 和第 9 列。
Output

对于每组输入,要求输出一行,该行包含精确的 R 的 n 次方。输出需要去掉前导的 0 后不要的 0 。如果输出是整数,不要输出小数点。
Sample Input

95.123 12
0.4321 20
5.1234 15
6.7592 9
98.999 10
1.0100 12
Sample Output

548815620517731830194541.899025343415715973535967221869852721
.00000005148554641076956121994511276767154838481760200726351203835429763013462401
43992025569.928573701266488041146654993318703707511666295476720493953024
29448126.764121021618164430206909037173276672
90429072743629540498.107596019456651774561044010001
1.126825030131969720661201
下面给出解题代码:

 

//对于每组输入,要求输出一行,该行包含精确的 R 的 n 次方。输出需要去掉前导的 0 后不要的 0 。如果输出是整数,不要输出小数点。
import java.util.*;
import java.math.*;
public class T1001 {
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		while(scan.hasNext())
		{
			BigDecimal bd = scan.nextBigDecimal();
			int p = scan.nextInt();
			String str = bd.pow(p).toPlainString();
			int endFlag = str.length();
			for(int i = endFlag-1; i >= 0; i--)
			{
				if(str.contains(".") && str.charAt(i) == '0')
					endFlag = i;
				else
					break;
			}
			str = str.substring(0, endFlag);
			if(str.startsWith("0."))
				str = str.substring(1);
			if(str.endsWith("."))
				str = str.substring(0,str.length()-1);
			System.out.println(str);
		}
	}
}
对于三道题中有不理解的地方可以留言!
 

 

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值