网站介绍模版,网站代运营推广,群晖 套件 wordpress,马云预测明年房价你知道的越多#xff0c;不知道的就越多#xff0c;业余的像一棵小草#xff01;你来#xff0c;我们一起精进#xff01;你不来#xff0c;我和你的竞争对手一起精进#xff01;编辑#xff1a;业余草zhuanlan.zhihu.com/p/94144867推荐#xff1a;https://www.xttbl… 你知道的越多不知道的就越多业余的像一棵小草你来我们一起精进你不来我和你的竞争对手一起精进编辑业余草zhuanlan.zhihu.com/p/94144867推荐https://www.xttblog.com/?p5116一律使用 BigDecimal避免后患一、背景总在项目中看到 Double 与 BigDecimal 被用错的情况竟然有人告诉我“一律使用 BigDecimal避免后患”我相信这位兄弟肯定是被精度问题搞蒙了因此我想同步一下我的使用姿势仅提供参考。二、两种类型使用过程中都有可能出坑double 的计算时容易出现不精确的问题double 的小数部分容易出现使用二进制无法准确表示。如十进制的0.10.20.30.4 都不能准确表示成二进制。具体原因相信大家都懂我就不多说了。如果有不懂的可以私信我或者评论留言dobule 的 比较要注意dobule 小数超过 15 位的相等比较就不一定对了。都是 true。BigDecimal 的除法除不尽会出现异常ArithmeticException所以使用 BigDecimal 进行除法运算一定要有精度new BigDecimal(double) 结果也许不是你想要的一般情况下都不使用 new BigDecimal(double) 应该使用 BigDecimal.valueOf(double)。BigDecimal d1 BigDecimal.valueOf(12.3);//结果是12.3 你预期的BigDecimal d2 new BigDecimal(12.3);//结果是12.300000000000000710542735760100185871124267578125我想 12.300000000000000710542735760100185871124267578125 肯定不是你想要的结果因此 new BigDecimal(double) 可能会产生不是你预期的结果原理可以自行看一下底层源代码还是比较容易搞懂的。另BigDecimal.valueOf(xxx) 是静态工厂类永远优先于构造函数(摘自《Effecitve java》此书也是非常推荐的一本经典书)BigDecimal 是不可变对象如原来 d11.11 又加了一个数 2.11这种操作要注意结果要指向新对象。任何针对BigDecimal对象的修改都会产生一个新对象BigDecimal newValue BigDecimal.valueOf(1.2222).add(BigDecimal.valueOf(2.33333));BigDecimal newValue BigDecimal.valueOf(1.2222).setScale(2);总之每次修改都要重新指向新对象才能保证计算结果是对的。BigDecimal 比较大小操作不方便毕竟是对象操作比较大小和相等都使用 compareTo如果需要返回大数或小数可使用 maxmin。且注意不能使用 equals。三、效率比较比如1 累加到 1000000(以本人机器 MacBookPro 2018 i7 2.2G)double 比 BigDecimal 快大约 10 倍double: 2msBigDecimal:16ms四、优缺点总结double 的优缺点double在计算过程中容易出现丢失精度问题使用方便有包装类可自动拆装箱计算效率高BigDecimal 的优缺点精度准确但做除法时要注意除不尽的异常BigDecimal 是对象类型也没有自动拆封箱机制操作起来总是有些不顺手五、使用场景推荐涉及到精准计算如金额一定要使用 BigDecimal 或转成 long 或 int 计算。若不需要精准的如一些统计值(本身就没有精确值)。用户平均价格店铺评分用户经纬度等本就没有精准值一说的推荐使用 double 或 float写代码更方便计算效率也高得多。值得一提的说如果 double 或 float 仅是用于传值并不会有精度问题但如果参与了计算就要小心了。要区分是不是需要精准值如果需要精准值需要转成 BigDecimal 计算以后再转成 double。但依然约定在 DTO 定义金额时使用 BigDecimal 或整形值是为了减少或避免 double 参与金额计算的机会避免出 bug。其他1代码中看到碰到让我觉得有问题的地方以下代码在不同的类中抓出来的觉得用得不太恰当的地方代码中真的不需要那么多地方使用 BigDecimal相反用到 BigDecimal 的地方并不多反而用 Double 的地方更多。以上代码我希望的方式是提醒DTO 中尽量使用包装类防止反系列化时 null 的造成的格式转换异常分析经纬度一般业务代码中也不太会去计算仅用于传给地图api等经纬度一般用于计算距离如果保留到 6 位小数时其实已经是 1 米级别的了也满足绝大多数场景了因此使用 Double 是确实是可行的店铺平均消费本身就是一个归纳统计值也一般用来比较大小做参考因此也用不着 BigDecimal当前价格这个不一样了为了减少 double 参与金钱计算统一使用 BigDecimal 代替带有小数的金额其他2关于 Mysql 中如何选用这两种类型首先与 java 不同的是 mysql 是用来持久化数据的而 java 中使用的数据一般更多的是过一下内存数据库都要除了指定数据类型指外还需要指定精度因此在 DB 中 Double 计算时精度的丢失比 Java 高得多因为 Java 默认精确到 15-16 位了更改数据类型的成本Mysql 比 Java 代码要难得多考虑到以上与 java 中不同几点做点个人使用总结与商业金融相关字段要使用 Decimal 来表示如金额费率等字段参与各类计算如加减乘除,sum,avg 等等也要使用 Decimal经纬度可以使用 double 来表示这个可参考 Java只要保证精度范围即可如果确实不确定使用什么 double 或 Decimal 哪种类型合适那最好使用 Decimal毕竟稳定安全高于一切注阿里的编码规范中强调统一带小数的类型一律使用 Decimal 类型也是有道理的使用Decimal 可以大大减少计算踩坑的概率。