BigDecimal 使用规范
菜逼直接无脑String转哈!避免精度丢失问题!
菜逼直接无脑String转哈!避免精度丢失问题!
菜逼直接无脑String转哈!避免精度丢失问题!
京东Java开发手册说:
禁止使用BigDecimal构造方法传入Double,可以使用对象.valueOf(Dubbo)
BigDecimal(double)的方式把double值转化为BigDecimal对象
• 最坏影响: 数据精度丢失文件名称:《京东JAVA代码规范-V1.0》
• 说明: BigDecimal(double)存在精度损失风险,在精确计算或值比较的场景中可能会导致业务逻辑异常。如:BigDecimal g = new BigDecimal(0.1f);
实际的存储值为:0. 1000000000000000055511151231257827021181583404541015625
正例:优先推荐入参为String的构造方法,或使用BigDecimal的valueOf()方法(此方法内部其实执行了Double的toString,而 Double的toString按double的实际能表达的精度对尾数进行了截断)。
BigDecimal介绍
Java在java.math包中提供的API类BigDecimal,一般情况下,对于不需要准确计算精度的数字,可以直接使用Float和Double处理,但是Double.valueOf(String) 和Float.valueOf(String)会丢失精度。所以如果需要精确计算的结果,则必须使用BigDecimal类来操作。
BigDecimal对象提供了传统的+、-、*、/等算术运算符对应的方法,通过这些方法进行相应的加减乘除操作。BigDecimal的值元素都是被Final修饰的,对象没被Final修饰。在进行每一次四则运算时,都会产生一个新的对象 ,所以在做加减乘除运算时要记得要保存操作后的值。
实战代码
字符转BigDecimal
整形、浮点型转BigDecimal
保留小数、四舍五入 setScale
拓展一下,舍入模式定义在RoundingMode枚举类中,共有8种:
- RoundingMode.UP:舍入远离零的舍入模式。在丢弃非零部分之前始终增加数字(始终对非零舍弃部分前面的数字加1)。注意,此舍入模式始终不会减少计算值的大小。
- RoundingMode.DOWN:接近零的舍入模式。在丢弃某部分之前始终不增加数字(从不对舍弃部分前面的数字加1,即截短)。注意,此舍入模式始终不会增加计算值的大小。
- RoundingMode.CEILING:接近正无穷大的舍入模式。如果 BigDecimal 为正,则舍入行为与 ROUNDUP 相同;如果为负,则舍入行为与 ROUNDDOWN 相同。注意,此舍入模式始终不会减少计算值。
- RoundingMode.FLOOR:接近负无穷大的舍入模式。如果 BigDecimal 为正,则舍入行为与 ROUNDDOWN 相同;如果为负,则舍入行为与 ROUNDUP 相同。注意,此舍入模式始终不会增加计算值。
- RoundingMode.HALF_UP:向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为向上舍入的舍入模式。如果舍弃部分 >= 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同。注意,这是我们在小学时学过的舍入模式(四舍五入)。
- RoundingMode.HALF_DOWN:向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为上舍入的舍入模式。如果舍弃部分 > 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同(五舍六入)。
- RoundingMode.HALF_EVEN:向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。如果舍弃部分左边的数字为奇数,则舍入行为与 ROUNDHALFUP 相同;如果为偶数,则舍入行为与 ROUNDHALF_DOWN 相同。注意,在重复进行一系列计算时,此舍入模式可以将累加错误减到最小。此舍入模式也称为“银行家舍入法”,主要在美国使用。四舍六入,五分两种情况。如果前一位为奇数,则入位,否则舍去。以下例子为保留小数点1位,那么这种舍入方式下的结果。1.15 ==> 1.2 ,1.25 ==> 1.2
- RoundingMode.UNNECESSARY:断言请求的操作具有精确的结果,因此不需要舍入。如果对获得精确结果的操作指定此舍入模式,则抛出ArithmeticException。
通常我们使用的四舍五入即RoundingMode.HALF_UP。
加 add
减 subtract
乘 multiply
除 divide
余数 remainder
相等比较 只能使用compareTo结果==0, 不得使用equals
我们比较数值是否相等的时候,一般使用==,但是这个是引用对象,只能使用equals方法,但是BigDecimal的equals执行:数值大小,精度比较!所以如果单纯比较数值的话,使用compareTo方法!
还没有评论,来说两句吧...