精确的数值计算BigDecimal

java中常用的表示小数类型有double,由于double最高只能支持16位有效数,且不一定能精确的表示10进制的小数,总是某个不确定的时候丢失精度,扰乱了程序的运行流程。所以只能用来做科学计算和工程计算。(16位的有效数足以使2进制数到10进制数的转换造成的误差在大部分科学计算和工程计算中小到可以忽略不计)

		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);
		double d = 1.1;
		System.out.println(d + 0.1);
		System.out.println(d - 10.1);
		System.out.println(d * 400);
		System.out.println(d / 100);
		d = 1.2;
		System.out.println(d + 0.1);
		System.out.println(d - 10.1);
		System.out.println(d * 400);
		System.out.println(d / 100);
/*
0.060000000000000005
0.5800000000000001
401.49999999999994
1.2329999999999999
1.2000000000000002
-9.0
440.00000000000006
0.011000000000000001
1.3
-8.9
480.0
0.012*/

在实际应用中,经常需要精确的运算和处理更大或者更小的数。为此Java在java.math包中提供了API类BigDecimal、BigInteger,用于商业计算。BigInteger只能运算整数,BigDecimal还可以运算小数,因此BigDecimal的适用范围更宽

  • BigDecimal的构造函数有很多个,建议不要用参数有double类型的,因为很可能10进制数转换为double类型数的时候,数的精度就降低了。
  • BigDecimal的非标度值就是一个没有小数点、没有指数、除去正负号后的第一个字符不能是"0"的字符串,且这个字符串表示的是一个10进制的整数。
  • BigDecimal的标度(scale)32 位的整数是小数点相对于某数的最小数位的位置,如果为零或正数,则标度是小数点后的位数。如果为负数,则将该数的非标度值乘以 10 的负 scale 次幂。因此,BigDecimal 表示的数值是 (unscaledValue × 10-scale)。 

 "0"            [0,0]
 "0.00"         [0,2]
 "123"          [123,0]
 "-123"         [-123,0]
 "1.23E3"       [123,-1]
 "1.23E+3"      [123,-1]
 "12.3E+7"      [123,-6]
 "12.0"         [120,1]
 "12.3"         [123,1]
 "0.00123"      [123,5]
 "-1.23E-12"    [-123,14]
 "1234.5E-4"    [12345,5]
 "0E+7"         [0,-7]
 "-0"           [0,0]

BigDecimal是不可变的,所以调用BigDecimal的成员函数返回的对象,很可能是一个新的对象,调用成员函数的对象却是相同不变的。

setScale(int newScale)方法声明小数点往右newScale位是需要保留的,再往右就是需要舍入的。

toString()  返回此 BigDecimal 的字符串表示形式,如果需要指数,则使用科学记数法。

toEngineeringString() 返回此 BigDecimal 的字符串表示形式,需要指数时,则使用工程计数法(指数一定是3的倍数如3、6、9、12)。

stripTrailingZeros() 返回数值上等于此小数,但从该表示形式移除所有尾部零的 BigDecimal。(经常返回用用科学计数法表示的数) 

toPlainString() 返回不带指数字段的此 BigDecimal 的字符串表示形式。(不要指数就用这个)

总结
        (1)商业计算使用BigDecimal。
        (2)尽量使用参数类型为String的构造函数。
        (3) BigDecimal都是不可变的(immutable)的,在进行每一步运算时,都会产生一个新的对象,所以在做加减乘除运算时千万要保存操作后的值。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值