1、 BigDecimal 类型数据 的创建,构造函数 有

 public BigDecimal(BigInteger intVal, long val, int scale, int prec);

 public BigDecimal(char[] in, int offset, int len) ;

 public BigDecimal(String val);

 public BigDecimal(double val);

 public BigDecimal(BigInteger val);

 public BigDecimal(int val);

 public BigDecimal(long val);

其中 构造方法

public BigDecimal(double val)

可能是不可预测的,因为double类型数据 有精度问题, 比如 double a = 0.1, new BigDecimal(a); 构造出来的BigDecimal 是不等于 0.1的, 解决方法是 将其转为String 或者用 。

         double a = 5.5D;
double b = 4.5D;
double c = 1.465D;
double d = 1.455D;
BigDecimal decimal = new BigDecimal(c).setScale(2, RoundingMode.HALF_EVEN); //构造的BigDecimal 不等于 1.465, 不精确 :1.4650000000000000799360577730112709105014801025390625
BigDecimal decimal2 = BigDecimal.valueOf(c).setScale(2, RoundingMode.HALF_EVEN); //这样构造的BigDecimal 才精确
BigDecimal decimal3 = new BigDecimal(c+"").setScale(2, RoundingMode.HALF_EVEN); //这样构造的BigDecimal 才精确 System.out.println(new BigDecimal(a).setScale(0, RoundingMode.HALF_EVEN).doubleValue());
System.out.println(new BigDecimal(b).setScale(0, RoundingMode.HALF_EVEN).doubleValue());
System.out.println(new BigDecimal(c+"").setScale(2, RoundingMode.HALF_EVEN).doubleValue());
System.out.println(new BigDecimal(d).setScale(2, RoundingMode.HALF_EVEN).doubleValue());

2、 BigDecimal 跟String 对象一样是不可变对象, 设置保留小数位数后 返回的是一个新的对象。

3、BigDecimal 舍入模式模式有 ROUNDING_UP 远离0, ROUNDING_DOWN 接近0, ROUNDING_CEILING 向上进位, ROUNDING_FLOOR 向下靠近, ROUNDING_HALF_UP 四舍五入, ROUNDING_HALF_DOWN 五舍六入, ROUNDING_HALF_EVEN 银行家舍入法,四舍六入,五后非零入,五后为零靠前位奇偶,前偶舍前奇入

    /**
* Rounding mode to round away from zero. Always increments the
* digit prior to a nonzero discarded fraction. Note that this rounding
* mode never decreases the magnitude of the calculated value.
*/
public final static int ROUND_UP = 0; /**
* Rounding mode to round towards zero. Never increments the digit
* prior to a discarded fraction (i.e., truncates). Note that this
* rounding mode never increases the magnitude of the calculated value.
*/
public final static int ROUND_DOWN = 1; /**
* Rounding mode to round towards positive infinity. If the
* {@code BigDecimal} is positive, behaves as for
* {@code ROUND_UP}; if negative, behaves as for
* {@code ROUND_DOWN}. Note that this rounding mode never
* decreases the calculated value.
*/
public final static int ROUND_CEILING = 2; /**
* Rounding mode to round towards negative infinity. If the
* {@code BigDecimal} is positive, behave as for
* {@code ROUND_DOWN}; if negative, behave as for
* {@code ROUND_UP}. Note that this rounding mode never
* increases the calculated value.
*/
public final static int ROUND_FLOOR = 3; /**
* Rounding mode to round towards {@literal "nearest neighbor"}
* unless both neighbors are equidistant, in which case round up.
* Behaves as for {@code ROUND_UP} if the discarded fraction is
* ≥ 0.5; otherwise, behaves as for {@code ROUND_DOWN}. Note
* that this is the rounding mode that most of us were taught in
* grade school.
*/
public final static int ROUND_HALF_UP = 4; /**
* Rounding mode to round towards {@literal "nearest neighbor"}
* unless both neighbors are equidistant, in which case round
* down. Behaves as for {@code ROUND_UP} if the discarded
* fraction is {@literal >} 0.5; otherwise, behaves as for
* {@code ROUND_DOWN}.
*/
public final static int ROUND_HALF_DOWN = 5; /**
* Rounding mode to round towards the {@literal "nearest neighbor"}
* unless both neighbors are equidistant, in which case, round
* towards the even neighbor. Behaves as for
* {@code ROUND_HALF_UP} if the digit to the left of the
* discarded fraction is odd; behaves as for
* {@code ROUND_HALF_DOWN} if it's even. Note that this is the
* rounding mode that minimizes cumulative error when applied
* repeatedly over a sequence of calculations.
*/
public final static int ROUND_HALF_EVEN = 6; /**
* Rounding mode to assert that the requested operation has an exact
* result, hence no rounding is necessary. If this rounding mode is
* specified on an operation that yields an inexact result, an
* {@code ArithmeticException} is thrown.
*/
public final static int ROUND_UNNECESSARY = 7;

4、 double 类型数据保存到 数据库的 decimal 类型字段时, mybatis是采用了 四舍五入的 舍入模式。

参考资料:

  1、提高你的Java代码质量吧:不容忽视的四舍五入细节 http://blog.csdn.net/p106786860/article/details/9377471

关于BigDecimal 和 double 类型保存金钱,以及精度问题,银行家舍入法的更多相关文章

  1. 两个Double类型相减出现精度丢失问题

    两个Double类型相减出现精度丢失问题 720.50-279.5=440.099999999 而不是440.1 解决方法,将数据库中的类型改为decimal类型,小数精确到2位

  2. java中如何使用BigDecimal使得Double类型保留两位有效数字

    一.场景:从数据表中读出Decimal类型的数据直接塞给Double类型的对象时,并不会有什么异常. 如果要再此基础上计算,就会发生异常. 比如:读出数据为0.0092,将其乘以100,则变成了0.9 ...

  3. Double 类型运算时的精度问题

    double 类型运算时的 计算的精度不高,常常会出现0.999999999999999这种情况,那么就须要用BigDecimal   它是java提供的用来高精度计算的工具类 以下是对这个类的一个包 ...

  4. 在使用hibernate注解的时候,想对double类型的字段进行精度约束

    @Column(name = "price",precision = 10,scale = 2) public double getPrice() { return price; ...

  5. double 类型运算会出现精度问题

    要先转换为字符串,后进行运算,可以写个方法做乘法运算public static double mul(double v1,double v2){BigDecimal b1 = new BigDecim ...

  6. BigDecimal初始化不要用double类型

    在进行单价.总价相关的计算时,就会用到BigDecimal. 在初始化时,一个不小心,就可能给自己挖坑. 示例如下: public class BigDecimalInitTest { public ...

  7. Java:利用BigDecimal类巧妙处理Double类型精度丢失

    目录 本篇要点 经典问题:浮点数精度丢失 十进制整数如何转化为二进制整数? 十进制小数如何转化为二进制数? 如何用BigDecimal解决double精度问题? new BigDecimal(doub ...

  8. MySQL中Decimal类型和Float Double的区别 & BigDecimal与Double使用场景

    MySQL中存在float,double等非标准数据类型,也有decimal这种标准数据类型. 其区别在于,float,double等非标准类型,在DB中保存的是近似值,而Decimal则以字符串的形 ...

  9. Java 中浮点数---------BigDecimal和double(初探)

    为什么要使用 bigdecimal? 借用<Effactive Java>这本书中的话,float和double类型的主要设计目标是为了科学计算和工程计算.他们执行二进制浮点运算,这是为了 ...

随机推荐

  1. 利用epoll写一个"迷你"的网络事件库

    epoll是linux下高性能的IO复用技术,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率.另一点原因就是获取 ...

  2. AutoCAD2006的安装及CASS7.1的配置破解

    -----本文只限于学习交流,商业用途请支持正版! -----转载请注明:http://www.cnblogs.com/mxbs/p/6193190.html 准备: AutoCAD2006.CASS ...

  3. .net session_end

    在做asp.net编程开发的时候,我遇见这样的问题,一个用户只能在一台机器上登录, 如果有用户在其他机器上登录,系统将提示该用户已经登录!当前登陆非法!我的做法是: 用Application变量保存已 ...

  4. 几个不错的webgl教程网

    http://ogldev.atspace.co.uk/index.html http://www.opengl-tutorial.org/ http://blog.wysaid.org/catego ...

  5. 【别人的老师VS你的老师 】同样是老师,差别怎么这么大呢!?

  6. bash/shell编程学习(2)

    先来复习上节重定向的用法: 1.快速清空文件 cat demo.txt < /dev/null 注:linux中有一个经典名言[一切皆文件],/dev/null可以认为是一个特殊的空文件,更形象 ...

  7. VS 报cmath(19): error C2061: 语法错误: 标识符“acosf” 错误

    这是因为我在.c文件中用了 #include <iostream> using namespace std; 这样编译的时候就报: 出现错误类型如下:1>c:\program fil ...

  8. SqlMetal.exe ORM代码生成

    作甚? 先说说这个工具是干啥的,我们所做的程序,或多或少需要存储一些数据到数据库,当然直接使用Sql语句也可以,甚至有些情况下就是要使用sql语句,但对于一些基本的增删改查,对每张表都要写查询语句就显 ...

  9. C#进阶系列——DDD领域驱动设计初探(三):仓储Repository(下)

    前言:上篇介绍了下仓储的代码架构示例以及简单分析了仓储了使用优势.本章还是继续来完善下仓储的设计.上章说了,仓储的最主要作用的分离领域层和具体的技术架构,使得领域层更加专注领域逻辑.那么涉及到具体的实 ...

  10. datatable刷新表头

    使用jQuery的datatable生成表格数据,当需要改变表头时,调用Table.fnDestroy();再重新创建表头 var oTable = null; function initSettin ...