`

处理大数字BigInteger与BigDecimal

 
阅读更多

关键技术剖析:

² BigInteger:支持任意精度的整数,可以精确地表示任意大小的整数值,同时在运算过程中不会丢失任何信息。

² BigDecimal:可以精确地表示任意精度的小数,同时在运算过程中不会丢失任何信息。

 

源码:

import java.math.BigDecimal;

import java.math.BigInteger;

 

 

public class BigNumber {

 

//默认除法运算精度,即保留小数点多少位 

private static final int DEFAULT_DIV_SCALE = 10;

 

//这个类不能实例化 

private BigNumber() {

}

 

 

public static double add(double v1, double v2) {

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

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

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

}

 

 

public static double sub(double v1, double v2) {

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

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

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

}

 

 

public static double mul(double v1, double v2) {

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

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

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

}

 

 

public static double div(double v1, double v2) {

return div(v1, v2, DEFAULT_DIV_SCALE);

}

 

 

public static double div(double v1, double v2, int scale) {

if (scale < 0) {

System.err.println("除法精度必须大于0!");

return 0;

}

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

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

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

}

 

 

public static BigInteger getFactorial(int n) {

if (n < 0) {

System.err.println("n必须大于等于0!");

return new BigInteger("-1");

else if (n == 0) {

return new BigInteger("0");

}

//将数组换成字符串后构造BigInteger

BigInteger result = new BigInteger("1");

for (; n > 0; n--) {

//将数字n转换成字符串后,再构造一个BigInteger对象,与现有结果做乘法

result = result.multiply(new BigInteger(new Integer(n).toString()));

}

return result;

}

 

public static void main(String[] args) {

 

// 如果我们编译运行下面这个程序会看到什么?

System.out.println(0.05 + 0.01);

System.out.println(1.0 - 0.42);

System.out.println(4.015 * 100);

System.out.println(123.3 / 100);

// 0.060000000000000005

// 0.5800000000000001

// 401.49999999999994

// 1.2329999999999999

 

//计算阶乘,可以将n设得更大

int n = 30;

System.out.println("计算n的阶乘" + n + "! = " + BigNumber.getFactorial(n));

 

//用double构造BigDecimal

BigDecimal bd1 = new BigDecimal(0.1);

System.out.println("(bd1 = new BigDecimal(0.1)) = " + bd1.toString());

//用String构造BigDecimal

BigDecimal bd2 = new BigDecimal("0.1");

System.out.println("(bd2 = new BigDecimal("0.1")) = "

+ bd2.toString());

 

BigDecimal bd3 = new BigDecimal("0.10");

//equals方法比较两个BigDecimal对象是否相等,相等返回true,不等返回false

System.out.println("bd2.equals(bd3) = " + bd2.equals(bd3));//false

//compareTo方法比较两个BigDecimal对象的大小,相等返回0,小于返回-1,大于返回1。

System.out.println("bd2.compareTo(bd3) = " + bd2.compareTo(bd3));//0

 

//进行精确计算

System.out.println("0.05 + 0.01 = " + BigNumber.add(0.05, 0.01));

System.out.println("1.0 - 0.42 = " + BigNumber.add(1.0, 0.42));

System.out.println("4.015 * 100 =" + BigNumber.add(4.015, 100));

System.out.println("123.3 / 100 = " + BigNumber.add(123.3, 100));

}

}

 

运行结果:

0.060000000000000005
0.5800000000000001
401.49999999999994
1.2329999999999999
计算n的阶乘30! = 265252859812191058636308480000000
(bd1 = new BigDecimal(0.1)) = 0.1000000000000000055511151231257827021181583404541015625
(bd2 = new BigDecimal("0.1")) = 0.1
bd2.equals(bd3) = false
bd2.compareTo(bd3) = 0
0.05 + 0.01 = 0.06
1.0 - 0.42 = 1.42
4.015 * 100 =104.015
123.3 / 100 = 223.3


源码分析:

² BigIntegerBigDecimal都是不可变的(immutable)的,在进行每一步运算时,都会产生一个新的对象,由于创建对象会引起开销,因此它们不适合于大量的数学运算,应尽量使用longfloatdouble等基本类型做科学计算或者工程计算。设计BigIntegerBigDecimal的目的是用来精确地表示大整数和小数,常用于商业计算中。

² BigDecimal够造方法的参数类型有4种,其中的两个用BigInteger构造,另一个是用double构造,还有一个使用String构造。应该避免使用double构造BigDecimal,因为:有些数字用double根本无法精确表示,传给BigDecimal构造方法时就已经不精确了。比如,new BigDecimal(0.1)得到的值是0.1000000000000000055511151231257827021181583404541015625。使用new BigDecimal("0.1")得到的值是0.1。因此,如果需要精确计算,用String构造BigDecimal,避免用double构造,尽管它看起来更简单! 

² equals()方法认为0.10.1是相等的,返回true,而认为0.100.1是不等的,结果返回false。方法compareTo()则认为0.10.1相等,0.100.1也相等。所以在从数值上比较两个BigDecimal值时,应该使用compareTo()而不是 equals()

分享到:
评论

相关推荐

    将 BigDecimal 类型转换为 Integer 类型.pdf

    其中,BigDecimal 是一种高精度的十进制浮点数类型,适合处理大数值计算。在一些需求中,我们可能需要将 BigDecimal 值转换为 Integer 类型。这时,可以使用 BigDecimal 的 intValue() 方法进行转换。 当 ...

    处理较大数字的PHP库.zip

    在PHP里提供了大数字的操作类,有的类是用于高精度计算,其中BigInteger类是针对大整数的处理类,而BigDecimal类则是针对大小数的处理类。下边我们介绍BigDecimal类:BigDecimal 的实现利用到了BigInteger,不同的是...

    bigNumber:用于将BigDecimal和BigInteger结合在一起的Java的bignum库

    bigNumber 这是Java的API,用于处理非常大的数字并对其进行计算。 基本上,它结合了Java的BigInteger和BigDecimal。 有关更多信息,请访问:

    Java大数字运算之BigInteger <font color=red>原创</font>

    在Java中提供了大数字的操作类,即 java.math.BigInteger 类与 java.math.BigDecimal 类。其中,BigInteger 类是针对大整数的处理类,这里有Integer 类的解释,使用方法和实例,需要的朋友可以参考下。

    BigInteger类,BigeDecimal类,Arrays类,包装类

    文章目录一.BigInteger类概念BigInteger类:构造方法二.BigDecimal类概念BigDecimal类:构造:方法:注意:解决:三.Arrays类概念特点方法四.包装类拆箱和装箱(自动)基本数据类型和字符串之间的转换 一.BigInteger...

    Java_Fraction

    一个实用分数类Fraction的Java实现关于本类的简要说明本Fraction类,结构和使用适当的java.math中提供的BigInteger和BigDecimal类,如果你曾使用或了解过这两个类型,那么对于本类,你同样能很快熟悉,它也远比那两...

    JavaAPI1.6中文chm文档 part1

    java.math 提供用于执行任意精度整数算法 (BigInteger) 和任意精度小数算法 (BigDecimal) 的类。 java.net 为实现网络应用程序提供类。 java.nio 定义作为数据容器的缓冲区,并提供其他 NIO 包的概述。 java.nio....

    JavaAPI中文chm文档 part2

    java.math 提供用于执行任意精度整数算法 (BigInteger) 和任意精度小数算法 (BigDecimal) 的类。 java.net 为实现网络应用程序提供类。 java.nio 定义作为数据容器的缓冲区,并提供其他 NIO 包的概述。 java.nio....

    break_eternity.js:一个Javascript数字库,用于表示大至10 ^^ 1e308和小至10 ^ -10 ^^ 1e308的数字。 break_infinity.js的续集,专为增量游戏而设计

    尽管处理的数字范围更广,但执行时间却是可比的(在测试中,其速度是break_infinity.js的2倍/0.5倍),并且具有相同的接口,因此可以用作break_infinity.js和十进制.js。 现在,您可以在喜欢的hyper 4运算符中使用...

    整理后java开发全套达内学习笔记(含练习)

    进行高精度运算可以用java.math包中BigDecimal类中的方法。 自动类型提升又称作隐式类型转换。 强制类型转换:int ti; (byte) ti ; 强制转换,丢弃高位 宣告变量名称的同时,加上“final”关键词来限定,这个...

Global site tag (gtag.js) - Google Analytics