Java.math学习笔记

来源:互联网 发布:面向对象编程的特点 编辑:程序博客网 时间:2024/05/05 11:48

图片没有粘上。。。明天把代码直接贴出来吧,不用图片了。


一 软件包 java.math 的描述

java.math包在API中的描述为:提供用于执行任意精度整数算法 (BigInteger) 和任意精度小数算法 (BigDecimal) 的类。

BigInteger 除提供任意精度之外,它类似于 Java 的基本整数类型,因此在 BigInteger 上执行的操作不产生溢出,也不会丢失精度。除标准算法操作外,BigInteger还提供模 (modular) 算法、GCD 计算、基本 (primality) 测试、素数生成、位处理以及一些其他操作。 BigDecimal提供适用于货币计算和类似计算的任意精度的有符号十进制数字。BigDecimal 允许用户对舍入行为进行完全控制,并允许用户选择所有八个舍入模式。

事实上,java.math包共包含三个类。除了描述中所提到的BigInteger和BigDecimal之外,还有一个MathContext。MathContext是封装上下文设置的不可变对象,它描述数字运算符的某些规则,例如由BigDecimal 类实现的规则。

1.1   大整数操作问题

 

1.2 float与double类型的计算精度问题

例子1.1

//例子1
  float a=(float) 0.05,b=(float) 0.01;
  System.out.println("a+b="+(a+b)); //应该等于0.06
  
  double c=11540.0,d=0.35;
  double result=c*d;
  System.out.println("result="+result); //应该等于4.39

输出结果:a+b=0.060000002

result=4038.9999999999995

显然,输出结果是不精确的,与真实值存在误差。

 

1.3 分析

    Java语言支持两种基本的浮点类型:float和double。java 的浮点类型都依据 IEEE 754 标准。IEEE 754 定义了32 位和 64 位双精度两种浮点二进制小数标准。

    IEEE 754 用科学记数法以底数为 2的小数来表示浮点数。32位浮点数用 1 位表示数字的符号,用 8位来表示指数,用 23位来表示尾数,即小数部分。作为有符号整数的指数可以有正负之分。小数部分用二进制(底数 2)小数来表示。对于64位双精度浮点数,用 1位表示数字的符号,用 11位表示指数,52位表示尾数。

Java中的浮点数类型float和double不能够进行精确运算。这个问题有时候非常严重,只要是超过精度能表示的范围就会产生误差。因此,产生的结果接近但不等于想要的结果。因此在使用 float double 作精确运算的时候要特别小心。在需要精确计算的场合必须考虑采用一些替代方案来实现。如通过 String结合 BigDecimal或者通过使用 long类型来转换。

 

二 java.math包详细介绍

2.1 BigInteger

2.1.1继承结构与实现接口

1)继承结构:

java.lang.Object
  java.lang.Number
       java.math.BigInteger
 

 

2)实现接口:Serializable, Comparable<BigDecimal>

3) java.lang.Number

     BigDecimal与BigInteger都扩展自Number这个抽象类。java.lang.Number继承自Object并实现了Serializable接口,是BigDecimalBigIntegerByteDoubleFloatIntegerLongShort 类的超类。

     Number本身有六个方法,包括四个抽象方法和两个具体方法。Number的子类必须提供将表示的数值转换为byte、double、float、int、long和short的方法。

四个抽象方法:(1)int intValue();(2)longlongValue();(3)float floatValue();

(4)double doubleValue();

两个具体方法:(1)byte byteValue();(2)short shortValue();

 

2.1.2详细描述

Java大整数类BigInteger继承于Number类并实现了Comparable接口,完全按照面向对象思想构建,因为Java语言没有在C++中编程实现运算符重载的概念,所以Java的BigInteger类是通过提供函数来实现各种大整数运算的。

BigInteger类为所有的Java原始整型操作以及所有在java.lang.Math中的相关方法提供相似的操作.另外BigInteger为求模运算,GCD计算,位操作等提供了运算。

算术运算的语义模仿了定义在Java语言规范中的Java的整型算术运算。比如,如果除数为0就会导致ArithmeticException(算术异常)等等。所有在规范中的溢出都将被忽略,因为BigIntegers将尽量适应运算结果的需要。

移位操作扩展了Java的移位操作,它允许负方向的移位。以负的位距来往右移就相当于往左移位。而无符号的右移运算符(>>>)就省略了。 而按位逻辑操作跟Java的按位操作是相似的。

比较运算执行有符号的整型比较,它跟Java的是相似的。

位逻辑运算操作严密的模仿了Java整型的位运算,二进制运算符(and,or,xor)对二个操作数中较短的那个执行符号扩展,优先于执行(and or xor)操作。

比较操作执行带符号整数比较, 类似于java的相关操作和相等操作的执行。

模数算术运算提供计算余数、执行乘幂等方法。这些方法总是返回一个非零的结果(介于0到modulus-1之间)。

位操作对二元运算的操作数执行单个的bit位操作,如果有必要, 为了操作数能包含指定的位,操作数是扩展了符号的。没有一个单独的位操作能生成一个不同符号的BigInteger,并且BigInteger类提供了无 限字长的抽象类,可以确保对前述的每个BigInteger有无限多个“虚符号位”。

对于BigInteger 的所有方法和构造函数,当传递的任何输入参数为空对象引用时就会抛出NullPointerException异常

 

2.1.3 BigInteger对大整数的表示

BigInteger类中,事实上使用了int mag[]数组来表示大整数,定义了一个int型变量signum来表示大整数的正负, Signum也是BigInteger的6个构造函数其中一个的参数。signum的有效值-1,0,1分别表示大整数负,零,正。如果signum不是有效值则抛出NumberFormatException异常。为确保对每一个大整数的值都有严密的表示,对大整数的零也要指明signum为0。这意味着BigInteger的零是一个0长度的mag 数组。

BigInteger通过以下6个构造函数来构造和表示大整数:

①BigInteger(byte[] val)

使用一个byte数组表示来构造一个大整数,

例2.1.1:

//例2.1.1
  byte[] val = new byte[2];
  for(int i= 0;i<val.length;i++)
  val[i]=2;
  BigInteger firsttest= new BigInteger(val);
  System.out.println("firsttest:"+firsttest);

输出结果:514,514的二进制表示是10,00000010

②BigInteger(int signum, byte[]magnitude)
用一个byte数组magnitude来构造大整数,用signum的-1,0,1来表示负,零,正。

例2.1.2:

byte[] magnitude = new byte[2];
  for(int i= 0;i<magnitude.length;i++)
  magnitude [i]=1;
  BigInteger secondtest= new BigInteger(-1,magnitude);
  System.out.println("secondtest:"+secondtest);

 

输出结果是-257.

257的二进制是1,00000001

 

③BigInteger(int bitLength, intcertainty, Random rnd)

构造一个随机产生的,正的,指定长度的,可能是素数的大整数,参数certainty指明要进行多少次素数测试. 其中bitLength指的是位长,即是转换为2进制有多少位。(使用的素数产生方法probablePrime()将在下文叙述)

例2.1.3:

 Random rr= new Random();
  BigInteger thirdtest= new BigInteger(100,10,rr);
  System.out.println("thirdtest:"+thirdtest);

 

④BigInteger(int numBits, Random rnd)

构造一个随机产生的大整数,范围在0到2^numBits – 1之间。 numBit指的也是位长,需要注意的是,这个构造函数总是用来产生非负的BigInteger。

例2.1.4:

Random rr = new Random();
  BigInteger fourthtest = new BigInteger(100,rr);
  System.out.println("fourthtest:"+fourthtest);

输出结果:fourthtest:613552490209764930750178768119

 

⑤BigInteger(String val)

转换十进制的字符串表达方式为BigInteger,这个字符串由一系列的10进制数字和可选择的负号组成,字符转数字的映射由Character.digit实现,这个字符串不能包含任意无关字符(例如:空格)。

例2.1.5:

这是最常用的构造函数,将字符串形式的数字作为参数。

 BigInteger fifthtest = new BigInteger("12345678901");
  System.out.println("fifthtest:"+fifthtest);

⑥BigInteger(String val, int radix)

转换字符串的表达式为指定(radix)进制的大整数,这个字符串由一系列的指定进制(radix)的数字组成,任意跟上负号,字符转数字的映射由Character.digit实现。同样,这个字符串不能包含任意无关字符(例如:空格)。

例2.1.6:

BigInteger sixthtest = new BigInteger("FF",16);
  System.out.println("sixthtest:"+sixthtest);

输出结果:255,

当用构造函数构造了BigInteger,就可以非常方便的调用BigInteger的各种方法对BigInteger进行操作,也可以用IO流的print()和println()方法直接输出BigInteger.

 

2.1.4 BigInteger的四则运算实现

对于BigInteger所有的算术操作,最基本的就是它的四则运算,四则运算也是其它一切运算的构建基础。

(1)add方法和subtract方法实际上进行的是数组对位相加和相减,这个过程用私有的函数来完成,返回的是为此重新分配空间的结果数组索引值(数组首地址)。然后再用结果数组来构造一个BigInteger作为最后的返回值。

(2)multiply方法使用的是数组相乘,用数组来模拟数字相乘,同样使用一个私有的函数来完成这个过程,为相乘结果数组分配新的空间,最后用结果数组来构造一个BigInteger 作为返回值。

(3)和java.lang.String 类型一样,BigInteger类也是不变的,所以任何在实例上进行的操作都将生成一个新的实例(创建对象),这个实例的值是操作的结果。所以 divide方法实现使用的是MutableBigInteger类,MutableBigInteger类不是公开的,它只供java.math类库内部使用。MutableBigInteger是BigInteger类的另一个版本,它的特点是不创建临时对象的前提上使调用程序得到象BigInteger类型的返回值(称为可变对象技术)。因为大整数的除法是由大量的其他算术操作组成的,所以需要大量的临时对象,而完成大量的操作而不创建新的对象可以极大地改善程序的性能,(因为创建对象的代价是很高的)所以在Java的大整数类中使用MutableBigInteger类中的方法来执行大整数除法。MutableBigInteger类包含在java.math包中,BigInteger类的divide方法使用了MutableBigInteger类的除法运算所返回的结果,使用这个MutableBigInteger类型的结果来构造一个BigInteger。

实际上在MutableBigInteger类中也使用了数组来模拟数字相除。


 

 

2.2 BigDecimal

2.2.1 继承结构与实现接口

1)继承结构:

java.lang.Object

  java.lang.Number

      java.math.BigDecimal

 

2)实现接口:Serializable, Comparable< >

 

2.2.2详细描述

BigDecimal是不可变的、任意精度的有符号十进制数,由任意精度的整数非标度值和32位的整数标度(scale)组成。如果为零或整数,则标度是小数点后的位数;如果为负数,则将该数的非标度值乘以10的负scale次幂。因此,BigDecimal 表示的数值是 (unscaledValue× 10^-scale)。

         BigDecimal 类提供以下操作:算术、标度操作、舍入、比较、哈希算法和格式转换。toString() 方法提供 BigDecimal 的规范表示形式。

BigDecimal 类使用户能完全控制舍入行为。如果未指定舍入模式,并且无法表示准确结果,则抛出一个异常;否则,通过向该操作提供适当的MathContext 对象,可以对已选择的精度和舍入模式执行计算。在任何情况下,可以为舍入控制提供八种舍入模式。使用此类(例如,ROUND_HALF_UP)中的整数字段来表示舍入模式已过时;应改为使用 RoundingModeenum(例如,RoundingMode.HALF_UP)的枚举值。

 

除了逻辑的准确结果外,每种算术运算都有一个表示结果的首选标度。下表列出了每个运算的首选标度。

算术运算结果的首选标度

运算

结果的首选标度

max(addend.scale(), augend.scale())

max(minuend.scale(), subtrahend.scale())

multiplier.scale() + multiplicand.scale()

dividend.scale() - divisor.scale()

这些标度是返回准确算术结果的方法使用的标度;准确相除可能必须使用较大的标度除外,因为准确的结果可能有较多的位数。例如,1/32 得到 0.03125。

舍入之前,逻辑的准确中间结果的标度是该运算的首选标度。如果用precision 位数无法表示准确的数值结果,则舍入会选择要返回的一组数字,并将该结果的标度从中间结果的标度减小到可以表示实际返回的precision 位数的最小标度。如果准确结果可以使用最多 precision个数字表示,则返回具有最接近首选标度的标度的结果表示形式。尤其是,通过移除结尾零并减少标度,可以用少于 precision个数字来表示准确的可表示的商。例如,使用floor 舍入模式将结果舍入为三个数字,
19/100 = 0.19 // integer=19,scale=2
但是21/110 = 0.190 // integer=190,scale=3

注意,对于加、减和乘,标度的缩减量将等于丢弃的准确结果的数字位置数。如果舍入导致进位传播创建一个新的高位,则当未创建新的数位时,会丢弃该结果的附加数字。

其他方法可能与舍入语义稍微不同。例如,使用指定的算法的 pow 方法得到的结果可能偶尔不同于舍入得到的算术结果,如最后一位有多个单位(ulp)。

可以通过两种类型的操作来处理BigDecimal 的标度:标度/舍入操作和小数点移动操作。标度/舍入操作(setScale 和round)返回 BigDecimal,其值近似地(或精确地)等于操作数的值,但是其标度或精度是指定的值;即:它们会增加或减少对其值具有最小影响的存储数的精度。小数点移动操作(movePointLeft 和movePointRight)返回从操作数创建的 BigDecimal,创建的方法是按指定方向将小数点移动一个指定距离。

 

2.2.3方法

双精度浮点型变量double可以处理16位有效数。在实际应用中,需要对更大或者更小的数进行运算和处理。Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。下面的两个表中列出了BigDecimal类的主要构造器和方法。

BigDecimal类的主要构造器和方法

构造器

描 述

BigDecimal(int)

创建一个具有参数所指定整数值的对象。

BigDecimal(double)

创建一个具有参数所指定双精度值的对象。

BigDecimal(long)

创建一个具有参数所指定长整数值的对象。

BigDecimal(String)

创建一个具有参数所指定以字符串表示的数值的对象。

 

方 法

描 述

add(BigDecimal)

BigDecimal对象中的值相加,然后返回这个对象。

subtract(BigDecimal)

BigDecimal对象中的值相减,然后返回这个对象。

multiply(BigDecimal)

BigDecimal对象中的值相乘,然后返回这个对象。

divide(BigDecimal)

BigDecimal对象中的值相除,然后返回这个对象。

toString()

将BigDecimal对象的数值转换成字符串。

doubleValue()

将BigDecimal对象中的值以双精度数返回。

floatValue()

将BigDecimal对象中的值以单精度数返回。

longValue()

将BigDecimal对象中的值以长整数返回。

intValue()

将BigDecimal对象中的值以整数返回。

注1:由于一般数值类型,例如double,不能准确地代表16位有效数以上的数字,在使用BigDecimal时,应用BigDecimal(String)构造器创建对象才有意义。另外,BigDecimal所创建的是对象,我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。

构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象。

 

注2:如果 BigDecimal 对象用作 SortedMap 中的键或 SortedSet 中的元素,则应特别小心,因为 BigDecimal 的自然排序与 equals 方法不一致。有关更多信息,参见Comparable、SortedMap 或 SortedSet。

当为任何输入参数传递 null对象引用时,此类的所有方法和构造方法都将抛出 NullPointerException。

 

2.2.4 示例与分析

需要注意的是,在进行精确计算时,一定要用String来构造BigDecimal。如果用double或者float来构造仍然无法得到精确的结果。

例子2.2.1

BigDecimal bd_a=new BigDecimal(Double.toString(0.05));
  BigDecimal bd_b=new BigDecimal(Double.toString(0.01));
  BigDecimal a_add_b=bd_a.add(bd_b);
  System.out.println("a_add_b="+a_add_b);BigDecimal bd_c=new BigDecimal(Double.toString(11540.0));
  BigDecimal bd_d=new BigDecimal(Double.toString(0.35));
  BigDecimal bd_result=bd_c.multiply(bd_d);
  System.out.println("bd_result="+bd_result);

输出结果:a_add_b=0.06

bd_result=4039.000

与实际的结果是一样的。

例子2.2.2 采用double型数字构造BigDecimal

BigDecimal bd_a=new BigDecimal(0.05);
  BigDecimal bd_b=new BigDecimal(0.01);
  BigDecimal a_add_b=bd_a.add(bd_b);
  System.out.println("a_add_b="+a_add_b);
  
  BigDecimal bd_c=new BigDecimal(11540.0);
  BigDecimal bd_d=new BigDecimal(0.35);
  BigDecimal bd_result=bd_c.multiply(bd_d);
  System.out.println("bd_result="+bd_result);

输出:

a_add_b=0.06000000000000000298372437868010820238851010799407958984375

bd_result=4038.99999999999974376052591651387047022581100463867187500

结果仍然是不准确的。

 

总结:上面两个例子表明,可以通过使用BigDecimal并且用String构造来解决精度问题,但是如果每做一次运算都要先将两个浮点数转换为String,然后构造成BigDecimal,在其中一个上调用add()(或者其他方法),传入另一个作为参数,最后再把运算的结果转换为浮点型(或字符串进行输出),是一个很繁琐的过程。因此可以自己编写一个工具类来简化操作,提供相应的方法封装上述过程,需要时直接调用指定的方法即可。

 

附录:工具类Arith

提供以下静态方法,包括加减乘除和四舍五入:

publicstaticdouble add(double v1,double v2)

publicstaticdouble sub(double v1,double v2)

publicstaticdouble mul(double v1,double v2)

publicstaticdouble div(double v1,double v2)

publicstaticdouble div(double v1,double v2,int scale)

publicstaticdouble round(double v,int scale)


 

2.3 MathContext

2.3.1继承结构与实现接口

1)继承结构:

         java.lang.Object
           java.math.MathContext

2)实现接口:Serializable

 

2.3.2 详细描述

MathContext是一个final类型,是一个不可变的对象。与java.math包的其他两个类不同,MathContext直接继承自Object,该对象封装了上下文设置,用于描述数字运算符的某些规则。

基本的独立设置包括:

1、  precision:某个操作使用的数字个数;结果舍入到此精度

2、  roundingMode:一个RoundingMode 对象,该对象指定舍入使用的算法。

 

2.3.3 字段信息

(1)UNLIMITED

public static final MathContext UNLIMITED

其设置具有无限精度算法所需值的 MathContext 对象。该设置的值为:precision=0roundingMode=HALF_UP

(2)DECIMAL32

public static final MathContext DECIMAL32

一个MathContext 对象,其精度设置与 IEEE 754R Decimal32 格式(即 7 个数字)匹配,舍入模式为 HALF_EVEN,这是 IEEE 754R 的默认舍入模式。

(3)DECIMAL64

public static final MathContext DECIMAL64

一个MathContext 对象,其精度设置与 IEEE 754R Decimal64 格式(即 16 个数字)匹配,舍入模式为 HALF_EVEN,这是 IEEE 754R 的默认舍入模式。

(4)DECIMAL128

public static final MathContext DECIMAL128

一个MathContext 对象,其精度设置与 IEEE 754R Decimal128 格式(即 34 个数字)匹配,舍入模式为HALF_EVEN,这是 IEEE 754R 的默认舍入模式。

 

2.3.4 使用

MathContext 通常不单独使用,而是与BigDecimal或BigInteger配合使用。以下是

一个例子,测试BigDecimal在不同的上下文设置下的输出:

 System.out.println(BigDecimal.class);
        System.out.println(BigDecimal.ROUND_CEILING);
        System.out.println(BigDecimal.ROUND_FLOOR);
        System.out.println(BigDecimal.ROUND_DOWN);
        System.out.println(BigDecimal.ROUND_UP);
        System.out.println(BigDecimal.ROUND_HALF_DOWN);
        System.out.println(BigDecimal.ROUND_HALF_EVEN);
        System.out.println(BigDecimal.ROUND_HALF_UP);
        //初始化
        System.out.println(new BigDecimal(new BigInteger("-123456")));
        System.out.println(new BigDecimal(-123456.8));
        //需要精确计算,非要用String来够造BigDecimal不可
        System.out.println(new BigDecimal("-123456.6"));
        System.out.println(new BigDecimal(new char[]{'2','4'}));
        System.out.println(new BigDecimal(new char[]{'2','4','3','9'},1,2));
       
        //int 标度
        System.out.println(new BigDecimal(new BigInteger("-123456"), 5));
        //根据上下文设置进行舍入
        System.out.println(new BigDecimal(new BigInteger("-123456"), 5, new MathContext(3, RoundingMode.UP)));
        System.out.println(new BigDecimal(123456.8, new MathContext(3, RoundingMode.HALF_DOWN)));
        System.out.println(new BigDecimal(123456, new MathContext(3, RoundingMode.CEILING)));
        System.out.println(new BigDecimal("123456", new MathContext(3, RoundingMode.DOWN)));
        System.out.println(new BigDecimal(123456.8, new MathContext(3, RoundingMode.FLOOR)));
        System.out.println(new BigDecimal(123456.8, new MathContext(3, RoundingMode.HALF_EVEN)));
        System.out.println(new BigDecimal(123456.8, new MathContext(3, RoundingMode.HALF_UP)));
        System.out.println(new BigDecimal(123456.8, new MathContext(3, RoundingMode.UP)));
        System.out.println(new BigDecimal(123456.8, new MathContext(3, RoundingMode.UP)).toPlainString());
        System.out.println(new BigDecimal(123456.8, new MathContext(3, RoundingMode.UP)).toEngineeringString());
       
        DecimalFormat df = new DecimalFormat("#.##");
        System.out.println(df.format(new BigDecimal(123456.856)));

 

三 Java.lang.Math类

3.1 概述

Math类是java.lang包下的一个final类,提供了用于进行指数、对数、平方根、三角函数的基本数学运算的函数以及一些数学常量。

         Math类中只有一个private的构造方法,因此无法获得Math的实例,只能使用其中包含的常量和函数。

3.2 常量

(1)Math.PI 圆周率,3.14159265358979323846

(2)Math.E 自然对数的底数,值为2.7182818284590452354

3.3 函数

Math.abs 求绝对值

Math.sin 正弦函数 Math.asin 反正弦函数

Math.cos 余弦函数 Math.acos 反余弦函数

Math.tan 正切函数 Math.atan 反正切函数 Math.atan2商的反正切函数

Math.toDegrees 弧度转化为角度 Math.toRadians 角度转化为弧度

Math.ceil 得到不小于某数的最大整数

Math.floor 得到不大于某数的最大整数

Math.IEEEremainder 求余

Math.max 求两数中最大

Math.min 求两数中最小

Math.sqrt 求开方

Math.pow 求某数的任意次方, 抛出ArithmeticException处理溢出异常

Math.exp 求e的任意次方

Math.log10 以10为底的对数

Math.log 自然对数

Math.rint 求距离某数最近的整数(可能比某数大,也可能比它小)

Math.round 同上,返回int型或者long型(上一个函数返回double型)

Math.random 返回0,1之间的一个随机数


 

 

四 附录:工具类Arith的源代码

源文件Arith.java

importjava.math.BigDecimal;

/**

 *由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精

 *确的浮点数运算,包括加减乘除和四舍五入。

 */

publicclassArith{

   //默认除法运算精度

   privatestaticfinalintDEF_DIV_SCALE =10;

   //这个类不能实例化

   private Arith(){

   }

 

   /**

    *提供精确的加法运算。

    *@paramv1被加数

    *@paramv2加数

    *@return两个参数的和

    */

   publicstaticdouble add(double v1,double v2){

       BigDecimal b1 = newBigDecimal(Double.toString(v1));

       BigDecimal b2 = newBigDecimal(Double.toString(v2));

       return b1.add(b2).doubleValue();

   }

   /**

    *提供精确的减法运算。

    *@paramv1被减数

    *@paramv2减数

    *@return两个参数的差

    */

   publicstaticdouble sub(double v1,double v2){

       BigDecimal b1 = newBigDecimal(Double.toString(v1));

       BigDecimal b2 = newBigDecimal(Double.toString(v2));

       return b1.subtract(b2).doubleValue();

   }

   /**

    *提供精确的乘法运算。

    *@paramv1被乘数

    *@paramv2乘数

    *@return两个参数的积

    */

   publicstaticdouble mul(double v1,double v2){

       BigDecimal b1 = newBigDecimal(Double.toString(v1));

       BigDecimal b2 = newBigDecimal(Double.toString(v2));

       return b1.multiply(b2).doubleValue();

   }

 

   /**

    *提供(相对)精确的除法运算,当发生除不尽的情况时,精确到

    *小数点以后10位,以后的数字四舍五入。

    *@paramv1被除数

    *@paramv2除数

    *@return两个参数的商

    */

   publicstaticdouble div(double v1,double v2){

       returndiv(v1,v2,DEF_DIV_SCALE);

   }

 

   /**

    *提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指

    *定精度,以后的数字四舍五入。

    *@paramv1被除数

    *@paramv2除数

    *@paramscale表示表示需要精确到小数点以后几位。

    *@return两个参数的商

    */

   publicstaticdouble div(double v1,double v2,intscale){

       if(scale<0){

           thrownewIllegalArgumentException(

               "The scale must be a positive integer or zero");

       }

       BigDecimal b1 = new BigDecimal(Double.toString(v1));

       BigDecimal b2 = newBigDecimal(Double.toString(v2));

   return

b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();

   }

 

   /**

    *提供精确的小数位四舍五入处理。

    *@paramv需要四舍五入的数字

    *@paramscale小数点后保留几位

    *@return四舍五入后的结果

    */

publicstaticdoubleround(double v,intscale){

       if(scale<0){

           thrownewIllegalArgumentException(

               "The scale must be a positive integer or zero");

       }

       BigDecimal b = newBigDecimal(Double.toString(v));

       BigDecimal one = new BigDecimal("1");

return

b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();

   }

};

原创粉丝点击