3.9 大数
如果基本整数和浮点类型的精度不够,可以在java.math包中找到几个方便的类:BigInteger
和BigDecimal
。这些类用于处理具有任意长数字序列的数字。BigInteger
类实现任意精度整数算术,BigDecimal
对浮点数也执行相同的操作。
使用静态的valueOf
方法将普通数字转换为大数:
BigInteger a = BigInteger.valueOf(100);
对于较长的数字,请使用带有字符串参数的构造函数:
BigInteger reallyBig = new BigInteger("22223224462942044552973989346190996720666693909")
也有常数BigInteger.ZERO
,BigInteger.ONE
,BigInteger.TEN
,并且,从Java 9开始,还有BigInteger.TWO
。
不幸的是,您不能使用熟悉的数学运算符(如+和*)组合大数字。相反,您必须在大数类中使用诸如加法和乘法之类的方法。
BigInteger c = a.add(b); // c = a + b
BigInteger d = c.multiply(b.add(BigInteger.valueOf(2))); // d = c * d
C++注意
与C++不同,Java没有可编程操作符重载。BigInteger类的编程人员无法重新定义+和*运算符,以给出BigInteger类的加法和乘法运算。语言设计者确实重载了+运算符来表示字符串的串联。他们选择不重载其他操作员,也没有给Java程序员机会在自己的类中重载操作符。
清单3.6显示了对清单3.5中彩票赔率程序的修改,并对其进行了更新,以便与大数字一起使用。例如,如果你被邀请参加抽奖,你需要从490个数字中选出60个数字,你可以使用这个程序告诉你你的获胜几率。它是1/7163958434619955574151622254009293341717612789263493493351,祝你好运!
清单3.5中的程序计算了语句
lotteryOdds = lotteryOdds * (n - i + 1) / i;
当使用大数字时,等价语句变为
lotteryOdds = lotteryOdds.multiply(BigInteger.valueOf(n - i + 1)).divide(BigInteger.valueOf(i));
清单3.6 BigIntegerTest/BigIntegerTest.java
import java.math.*;
import java.util.*;
/**
* This program uses big numbers to compute the odds of winning the grand prize in a lottery.
* @version 1.20 2004-02-10
* @author Cay Horstmann
*/
public class BigIntegerTest
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
System.out.print("How many numbers do you need to draw? ");
int k = in.nextInt();
System.out.print("What is the highest number you can draw? ");
int n = in.nextInt();
/*
* compute binomial coefficient n*(n-1)*(n-2)*...*(n-k+1)/(1*2*3*...*k)
*/
BigInteger lotteryOdds = BigInteger.valueOf(1);
for (int i = 1; i <= k; i++)
lotteryOdds = lotteryOdds.multiply(BigInteger.valueOf(n - i + 1)).divide(
BigInteger.valueOf(i));
System.out.println("Your odds are 1 in " + lotteryOdds + ". Good luck!");
}
}
java.math.BigInteger 1.1
- BigInteger add(BigInteger other)
- BigInteger subtract(BigInteger other)
- BigInteger multiply(BigInteger other)
- BigInteger divide(BigInteger other)
- BigInteger mod(BigInteger other)
返回此大整数和其他整数的和、差、积、商和余数。 - BigInteger sqrt() 9
生成此大整数的平方根。 - int compareTo(BigInteger other)
如果此大整数等于其他整数,则返回0;如果此大整数小于其他整数,则返回负结果;否则返回正结果。 - static BigInteger valueOf(long x)
返回值等于x的大整数。
java.math.BigDecimal 1.1
- BigDecimal add(BigDecimal other)
- BigDecimal subtract(BigDecimal other)
- BigDecimal multiply(BigDecimal other)
- BigDecimal divide(BigDecimal other)
- BigDecimal divide(BigDecimal other, RoundingMode mode) 5
返回此大十进制数和其他数的和、差、积或商。如果商没有有限的十进制展开,则第一个除法将引发异常。要获得四舍五入的结果,请使用第二种方法。模式RoundingMode.HALF_UP
是您在学校学习的舍入模式:将数字0到4舍弃,将数字5到9进位。它适用于常规计算。有关其他舍入模式,请参阅API文档。 - int compareTo(BigDecimal other)
如果此大小数等于Other,则返回0;如果此大小数小于Other,则返回负结果;否则返回正结果。 - static BigDecimal valueOf(long x)
- static BigDecimal valueOf(long x, int scale)
返回一个大小数,其值等于x或x/(10^scale)。