概述
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)的,在进行每一步运算时,都会产生一个新的对象,所以在做加减乘除运算时千万要保存操作后的值。
最后
以上就是激情百合为你收集整理的精确的数值计算BigDecimal的全部内容,希望文章能够帮你解决精确的数值计算BigDecimal所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复