3.10 大数值和数学函数
(1)大数值
如果基本的整数和浮点数精度不能够满足需求,可以使用java.math包中的两个很有用的类:Biginteger和BigDecimal。这两个类可以处理包含任意长度数字序列的数值。Biginteger类实现了任意精度的整数运算,BigDecimal实现了任意精度的浮点数运算。
使用静态的valueOf方法可以将普通的数值转换为大数值:
BigInteger a = BigInteger.valueOf(100);
但要注意:大数值类不能使用+、-、*这类运算符(Java没有对这些运算符进行重载),而需要使用大数值类中的add和multiply方法,如:
BigInteger c = a.add(b); //c = a + b
BigInteger d = c.multiply(b.add(BigInteger.valueOf(2)));//d=c*(b+2)
java.math.BigInteger常用API
BigInteger add(BigInteger other) BigInteger subtract(BigInteger other) BigInteger multiply(BigInteger other) BigInteger divide(BigInteger other) BigInteger mod(BigInteger other) 返回这个大整数和另一个大整数other的和、差、积、商以及余数 |
int compareTo(BigInteger other) 如果两个大整数相等,返回0;如果这个大整数小于另一个大整数other,返回负数;否则,返回正数。 |
static BigInteger valueOf(long x) 返回值等于x的大整数。 |
java.math.BigDecimal常用API
BigDecimal add (BigDecimal other) BigDecimal subtract (BigDecimal other) BigDecimal multiply (BigDecimal other) BigDecimal divide (BigDecimal other,RoundingMode mode) jdk5.0 返回一个大实数与另一个大实数other的和、差、积、商。要想计算商,必须给出舍入方式(rounding mode)。例如RoundingMode.HALF_UP是常规的四舍五入方式,用于常规计算。其他舍入方式参看API文档。 |
int compareTo (BigDecimal other) 同BigInteger的同名方法 |
static BigDecimal valueOf(long x) static BigDecimal valueOf(long x,int scale) 返回值为x或x/10scale的一个大实数。 |
例子:比较long、double和大数值类的算术运算
测试代码如下
import java.math.BigInteger; import java.math.BigDecimal; import java.math.RoundingMode; public class SecondSample { public static void main(String[] args) { long x=9223372036854775807L,y=2L; //x为long的最大值 double a=2.0,b=1.1; BigInteger bx=BigInteger.valueOf(x); BigInteger by=BigInteger.valueOf(y); BigDecimal ba=BigDecimal.valueOf(a); BigDecimal bb=BigDecimal.valueOf(b); System.out.println("long x+y="+(x+y)); System.out.println("Big bx+by="+bx.add(by)); System.out.println("long x-y="+(x-y)); System.out.println("Big bx-by="+bx.subtract(by)); System.out.println("long x*y="+(x*y)); System.out.println("Big bx*by="+bx.multiply(by)); System.out.println("long x/y="+(x/y)); System.out.println("Big bx/by="+bx.divide(by)); System.out.println("long x%y="+(x%y)); System.out.println("Big bx%by="+bx.mod(by)); System.out.println("----------------------"); System.out.println("double a+b="+(a+b)); System.out.println("Big ba+bb="+ba.add(bb)); System.out.println("doube a-b="+(a-b)); System.out.println("Big ba-bb="+ba.subtract(bb)); System.out.println("double a*b="+(a*b)); System.out.println("Big ba*bb="+ba.multiply(bb)); System.out.println("double a/b="+(a/b)); System.out.println("Big ba/bb="+ba.divide(bb,RoundingMode.HALF_UP)); } } |
计算结果如下:
long x+y=-9223372036854775807 //溢出 Big bx+by=9223372036854775809 //比较x+y long x-y=9223372036854775805 Big bx-by=9223372036854775805 long x*y=-2 //溢出 Big bx*by=18446744073709551614 //比较x*y long x/y=4611686018427387903 Big bx/by=4611686018427387903 long x%y=1 Big bx%by=1 ---------------------- double a+b=3.1 Big ba+bb=3.1 doube a-b=0.8999999999999999 // 二进制无法精确表达1/10 Big ba-bb=0.9 //比较a-b double a*b=2.2 Big ba*bb=2.20 double a/b=1.8181818181818181 Big ba/bb=1.8 // 四舍五入 |
(2)数学函数与常量
在java.lang.Math类中,包含了各类数学函数(通常以静态方法出现)和常量。
Math常用API摘要
算术运算 |
|
| |
| |
| |
| |
| |
| |
| |
幂、指数和对数运算 |
|
| |
| |
| |
| |
| |
三角函数运算 |
|
|
其他运算参看API文档
同时,Java还提供了两个用于表示圆周率和e常量的近似值
static double E 比任何其他值都更接近 e(即自然对数的底数)的 |
static double PI 比任何其他值都更接近 pi(即圆的周长与直径之比)的 |
从JDK5.0开始,可以不必在数学方法名和常量名前添加前缀“Math.”,只要在在源文件顶部静态导入即可,import static java.lang.Math.*;
注:在Math类中,为了达到最快的性能,所有方法都使用计算机浮点单元中的例程。如果认为得到一个完全可预测的结果(各平台上得到的结果相同)比运行速度要重要的话,可以使用StrictMath类,它使用“自由发布的Math库(fdlibm)”实现算法。