ACM/ICPC竞赛中会遇到许多高精度计算的题目,比如两个大整数相加(1111111111111111111111111111111111111111 + 22222343259435894305894301243)。如果我们还采用普通类型比如long long来存储这些值,是装不下这么大的值的了。
我们通常的做法是以字符串的形式保存值,然后编程模拟人的计算过程,例如
X = “111”;
Y = “999”;
X + Y用如下方法计算:
1 1 1
+ 9 9 9
————————
10 10 10
然后再逐一进位得到“1110”。
减法,乘法,除法都是基于字符串模拟的基础之上的。
同时Java类库提供了高精度运算的类java.math.BigInteger和java.math.BigDecimal,这样我们在比赛时就可以使用这两个类完成高精度计算的要求。
BigInteger用于任意精度的整数的运算:
例:
BigInteger x = new BigInteger(“11111111111111111111111111111111111111”);
BigInteger y = new BigInteger(“22222343259435894305894301243”);
System.out.println(x .add(y));
BigInteger类:
abs() 返回其值是此BigInteger的绝对值的BigInteger。
compareTo(BigInteger val) 将此BigInteger与指定的BigInteger进行比较。
divide(BigInteger val) 返回其值为 (this / val) 的BigInteger。
pow(int exponent) 返回其值为 (thisexponent) 的BigInteger。
multiply(BigInteger val) 返回其值为 (this * val) 的BigInteger。
gcd(BigInteger val) 返回一个 BigInteger,其值是 abs(this) 和 abs(val) 的最大公约数。
subtract(BigInteger val) 返回其值为 (this - val) 的 BigInteger。
BigDecimal类:
BigDecimal(String val)
将 BigDecimal 的字符串表示形式转换为 BigDecimal。
abs()
返回 BigDecimal,其值为此 BigDecimal 的绝对值,其标度为 this.scale()。
add(BigDecimal augend)
返回一个 BigDecimal,其值为 (this + augend),其标度为 max(this.scale(), augend.scale())。
compareTo(BigDecimal val)
将此 BigDecimal 与指定的 BigDecimal 比较。
divide(BigDecimal divisor, int scale, int roundingMode)
返回一个 BigDecimal,其值为 (this / divisor),其标度为指定标度。
RoundingMode
CEILING
向正无限大方向舍入的舍入模式。
DOWN
向零方向舍入的舍入模式。
FLOOR
向负无限大方向舍入的舍入模式。
HALF_DOWN
向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向下舍入。
HALF_EVEN
向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。
HALF_UP
向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向上舍入。
UNNECESSARY
用于断言请求的操作具有精确结果的舍入模式,因此不需要舍入。
UP
远离零方向舍入的舍入模式。
setScale(int newScale, RoundingMode roundingMode)
返回 BigDecimal,其标度为指定值,其非标度值通过此 BigDecimal 的非标度值乘以或除以十的适当次幂来确定,以维护其总值。
subtract(BigDecimal subtrahend)
返回一个 BigDecimal,其值为 (this - subtrahend),其标度为 max(this.scale(), subtrahend.scale())。
divide(BigDecimal divisor, RoundingMode roundingMode)
返回一个 BigDecimal,其值为 (this / divisor),其标度为 this.scale()。
更多的函数请参考javaAPI文档。
TOJ 1436 小数A+B
import java.io.*;
import java.util.*;
import java.math.*;
import java.text.*;
public class Main {
public static void main(String[] args) {
Scanner cin=new Scanner(System.in);
while(cin.hasNext()) {
BigDecimal a=cin.nextBigDecimal();
BigDecimal b=cin.nextBigDecimal();
String out=new String(a.add(b).toString());
//去掉前导零
int p=0;
while(out.charAt(p)=='0')p++;
//去掉小数点后多余的零
int q=out.length()-1;
while(out.charAt(q)=='0')q--;
if(out.charAt(q)=='.')q--;
for(int i=p;i<=q;i++)
System.out.print(out.charAt(i));
System.out.println();
}
}
}