jeffsui / jeffsui.github.io

pinghailinfeng's blog main website
http://jeffsui.github.io
7 stars 5 forks source link

java小数精度和四舍五入 #109

Open jeffsui opened 4 years ago

jeffsui commented 4 years ago

java中的小数

java中小数数值计算无法保证绝对精准,只能保证一定精度范围,比如,两个double数,不应该使用等号判定是否相等,因为> > 相等的两个double数存储在计算机中可能不相等(计算机存储位数)。 尤其是除法,只能保留一定范围的小数,精度取决于该类型在计算机的位数 编程时需要注意的问题 doulbe类型的数,不能用等号判定是否相等(或者是一定范围内可以)。因为两次同样的计算(除法)结果可能出现小数部分不同。甚至极端的时候,初始化两个小数时,都可能不相等(用数值和字符串分别初始化bigdecimal的小数就会不等)

java中专门用于计算小数的类BigDemical

float和double只能用来做科学计算或者是工程计算,在广域数值范围上提供较为精确的快速近似计算;而在商业计算要求结果精确(比如,有的编程语言中提供了专门的货币类型来处理),所以Java使用java.math.BigDecimal专门处理小数精度

构造方法


   BigDecimal(int)       创建一个具有参数所指定整数值的对象。 
    BigDecimal(double)    创建一个具有参数所指定双精度值的对象。 
    BigDecimal(long)      创建一个具有参数所指定长整数值的对象。 
    BigDecimal(String)    创建一个具有参数所指定以字符串表示的数值的对象。

四舍五入

java中四舍五入方法

Math类中的round方法不能设置保留几位小数,但可以乘100达到保留2位的目的:
        Math.round(value*100)/100.0;

或者,直接用java.text.DecimalFormat指定保留几位小数,用哪几种舍入法:
        DecimalFormat decFormat = new DecimalFormat("#.00");
        decFormat.setRoundingMode(RoundingMode.HALF_UP);

java中java的8种舍入方式:

1、 ROUND_UP:向上取整(丢掉小数,整数加1) 远离零方向舍入。向绝对值最大的方向舍入,只要舍弃位非0即进位。

2、ROUND_DOWN:向下取整(丢掉小数)。趋向零方向舍入。向绝对值最小的方向输入,所有的位都要舍弃,不存在进位情况。

3、ROUND_CEILING:向正无穷方向走,始终不会减少计算值。如果 BigDecimal 为正,则舍入行为与 ROUND_UP 相同;如果为负,则舍入行为与 ROUND_DOWN 相同。Math.round()方法就是使用的此模式。

4、ROUND_FLOOR:向负无穷方向舍入。向负无穷方向靠拢。若是正数,舍入行为类似于ROUND_DOWN;若为负数,舍入行为类似于ROUND_UP。

5、 HALF_UP:四舍五入,最近数字舍入(5进)。

6、 HALF_DOWN:四舍六入,最近数字舍入(5舍)。

7、 HAIL_EVEN:银行家舍入法。四舍六入五偶舍。即舍弃位4舍6入,当为5时看前一位,奇进偶舍。向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。 也就是说,如果舍弃部分左边的数字为奇数,则舍入行为与 ROUND_HALF_UP 相同; 如果为偶数,则舍入行为与 ROUND_HALF_DOWN 相同。 注意,在重复进行一系列计算时,此舍入模式可以将累加错误减到最小。

8、ROUND_UNNECESSARY 断言请求的操作具有精确的结果,因此不需要舍入。如果对获得精确结果的操作指定此舍入模式,则抛出ArithmeticException。