随笔

461 阅读2分钟

今天,在写提现的时候,我看到了一个数据类型 BigDecimal,这个类型创建出来的目的,好像是为了避免数据的精度问题。 例如:

public class BigDecimal {
    public static void main(String[] args) {
        System.out.println(0.1 +0.2);
    }
}
/*
        0.30000000000000004
 */

计算机是二进制的 而这里计算的是十进制,在浮点数的精度中这里的精度转换是会出现精度丢失的问题。 因此,在账户等有关金钱的计算时为了防止这种事情发生,就设计了这样的类型。 在看代码的时候,

BigDecimal bigDecimal = new BigDecimal(amount).setScale(0, BigDecimal.ROUND_HALF_UP);

有一个setScale方法,这个方法对数据进行四舍五入的:

setScale(1)表示保留一位小数,默认用四舍五入方式 
setScale(1,BigDecimal.ROUND_DOWN)直接删除多余的小数位,如2.35会变成2.3 
setScale(1,BigDecimal.ROUND_UP)进位处理,2.35变成2.4 
setScale(1,BigDecimal.ROUND_HALF_UP)四舍五入,2.35变成2.4

setScaler(1,BigDecimal.ROUND_HALF_DOWN)四舍五入,2.35变成2.3,如果是5则向下舍

舍入模式从零舍入。 始终在非零丢弃分数之前增加数字。 
请注意,这种舍入模式永远不会降低计算值的大小。
public final static int ROUND_UP = 0;

舍入模式向零舍入。 从不增加丢弃分数之前的数字(即截断)。 
请注意,这种舍入模式永远不会增加计算值的大小。
public final static int ROUND_DOWN =         1;

舍入模式向正无穷大舍入。 如果BigDecimal为正,则表现与ROUND_UP ;
如果为负,则表现与ROUND_DOWN 。 请注意,此舍入模式永远不会减少计算值。
public final static int ROUND_CEILING =      2;

舍入模式向负无穷大舍入。 
如果BigDecimal为正,则表现与ROUND_DOWN ; 
如果为负,则表现与ROUND_UP 。 请注意,此舍入模式永远不会增加计算值。
public final static int ROUND_FLOOR =        3;

舍入模式向“最近的邻居”舍入,除非两个邻居是等距的,在这种情况下向上舍入。 
如果丢弃的分数 ≥ 0.5,则与ROUND_UP ;
否则,行为与ROUND_DOWN 。 请注意,这是我们大多数人在小学时所教的舍入模式。
public final static int ROUND_HALF_UP =      4;

舍入模式向“最近的邻居”舍入,除非两个邻居是等距的,在这种情况下向下舍入。
如果丢弃的分数 > 0.5,则表现与ROUND_UP ; 否则,行为与ROUND_DOWN 。
public final static int ROUND_HALF_DOWN =    5;

舍入模式向“最近的邻居”舍入,除非两个邻居是等距的,在这种情况下,向偶数邻居舍入。
如果丢弃的分数左边的数字是奇数,则表现与ROUND_HALF_UP一样;
如果它是偶数,则表现为ROUND_HALF_DOWN 。 
请注意,这是一种舍入模式,可在对一系列计算重复应用时最大限度地减少累积误差。
public final static int ROUND_HALF_EVEN =    6;

舍入模式断言所请求的操作具有精确的结果,因此不需要舍入。
如果在产生不精确结果的操作上指定此舍入模式,则会引发ArithmeticException 。
public final static int ROUND_UNNECESSARY =  7;