近期经常接触支付相关的功能,在开发及测试过程中,开始金额都使用的是double类型,而近期新进的需求存在支付时打折的情况,也就是会出现如 1.23元的情况,那么这时候问题来了,如果是直接使用1.23进行支付都是不存在问题的。而偏偏在支付前通常需要一些计算。我们的系统支持会员余额与三方支付(微信、支付宝)同时进行,比如一笔待支付的订单是12.8员,其中用户有5块钱的会员余额,剩下的7.8元通过三方支付进行(这里使用微信吧),那么就涉及到double减法,同时微信支付时需要将元转为分,就是7.8x100,这又涉及到了乘法,此时就出现了double精度计算的问题。如下例子:

double a = 12.3d;
double b = 5d;
System.out.println(a-b); // 7.300000000000001 double c= 1.13d;
System.out.println(c * 100); // 112.99999999999999

上面的计算存在了精度问题,这样计算还需要进行四舍五入,比较麻烦。因此我们想到使用BigDecimal来实现小数的计算。最简单的加减乘除运算如下,希望可以帮到遇到同样问题的童鞋:

package com.blacksonny.utils;

import java.math.BigDecimal;

/**
* Created by kk on 2015/12/28.<br>
*/
public class NumericUtils { /**
* double 加运算
*
* @param a
* @param b
* @return
*/
public static double add(double a, double b) {
BigDecimal b1 = new BigDecimal(Double.toString(a));
BigDecimal b2 = new BigDecimal(Double.toString(b));
return b1.add(b2).doubleValue();
} /**
* float 加运算
*
* @param a
* @param b
* @return
*/
public static float add(float a, float b) {
BigDecimal b1 = new BigDecimal(Double.toString(a));
BigDecimal b2 = new BigDecimal(Double.toString(b));
return b1.add(b2).floatValue();
} /**
* double 减运算
*
* @param a
* @param b
* @return
*/
public static double subtract(double a, double b) {
BigDecimal b1 = new BigDecimal(Double.toString(a));
BigDecimal b2 = new BigDecimal(Double.toString(b));
return b1.subtract(b2).doubleValue();
} /**
* float 减运算
*
* @param a
* @param b
* @return
*/
public static float subtract(float a, float b) {
BigDecimal b1 = new BigDecimal(Double.toString(a));
BigDecimal b2 = new BigDecimal(Double.toString(b));
return b1.subtract(b2).floatValue();
} /**
* double 乘运算
*
* @param a
* @param b
* @return
*/
public static double multiply(double a, double b) {
BigDecimal b1 = new BigDecimal(Double.toString(a));
BigDecimal b2 = new BigDecimal(Double.toString(b));
return b1.multiply(b2).doubleValue();
} /**
* float 乘运算
*
* @param a
* @param b
* @return
*/
public static float multiply(float a, float b) {
BigDecimal b1 = new BigDecimal(Double.toString(a));
BigDecimal b2 = new BigDecimal(Double.toString(b));
return b1.multiply(b2).floatValue();
} /**
* double 除运算
*
* @param a
* @param b
* @return
*/
public static double divide(double a, double b) {
BigDecimal b1 = new BigDecimal(Double.toString(a));
BigDecimal b2 = new BigDecimal(Double.toString(b));
return b1.divide(b2).doubleValue();
} /**
* float 除运算
*
* @param a
* @param b
* @return
*/
public static float divide(float a, float b) {
BigDecimal b1 = new BigDecimal(Double.toString(a));
BigDecimal b2 = new BigDecimal(Double.toString(b));
return b1.divide(b2).floatValue();
}
}

另外在javascript中也存在精度计算的问题,没有什么好的方法,计算时使用parseFloat先转换,再取精度,写法为 parseFloat(xx.xxx).toFixed(2); //2表示取两位小数。

同时对于常用的需要将一个double转为BigDecimal时,应该使用BigDecimal.valueOf(0.1), 或者new BigDecimal("0.1"), 而不要直接将double类型作为构造方法的入参传入,这种写法有精度的问题。

double精度的坑与BigDecimal的更多相关文章

  1. Java中关于 BigDecimal 的一个导致double精度损失的"bug"

    背景 在博客 恶心的0.5四舍五入问题 一文中看到一个关于 0.5 不能正确的四舍五入的问题.主要说的是 double 转换到 BigDecimal 后,进行四舍五入得不到正确的结果: public ...

  2. java 常用类库:BigInteger大整数;BigDecimal大小数(解决double精度损失);

    大整数BigInteger package com.zmd.common_class_libraries; import java.math.BigInteger; /** * @ClassName ...

  3. java float、double精度研究(转)

    在java中运行一下代码System.out.println(2.00-1.10);输出的结果是:0.8999999999999999很奇怪,并不是我们想要的值0.9 再运行如下代码:System.o ...

  4. Java Double 精度问题总结

    package Demo_1.Test_2; import java.math.BigDecimal; /** * @描述:Java Double 精度问题总结 * @详细描述:使用Java,doub ...

  5. Java面试官:兄弟,你确定double精度比float低吗?

    我有一个朋友,叫老刘,戴着度数比我还高的近视镜,显得格外的"程序员":穿着也非常"不拘一格",上半身是衬衣西服,下半身是牛仔裤运动鞋. 我和老刘的感情非常好,每 ...

  6. 【Double】double精度问题和int、long除不尽取舍问题

    看了老半天,真心没搞懂,留下几篇文章,后面继续跟进吧.... 一.如何理解double精度丢失问题? - 知乎 https://www.zhihu.com/question/42024389/answ ...

  7. js double 精度损失 bugs

    js double 精度损失 bugs const arr = [ 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01 ]; // [ ...

  8. BigDecimal 解决double精度丢失问题(加减乘除)

    package com.qcloud.component.publicservice.util; import java.math.BigDecimal; /** * 由于Java的简单类型不能够精确 ...

  9. float和double精度问题

    System.out.println(new BigDecimal(253.90).doubleValue() * 100);25390.0精度正确 System.out.println(new Bi ...

随机推荐

  1. js判断访问者是否来自移动端代码

    <script type="text/javascript"> function is_mobile() { var regex_match = /(nokia|iph ...

  2. 表达式求值 (栈) 用C++实现

    #include <cstdio> #include <cstdlib> #include <cmath> #include <stack> #incl ...

  3. 配置NTP时间服务器

    一.安装ntp软件 1.检查是否安装了ntp相关包. rpm -qa | grep ntp 2.安装ntp软件. yum -y install ntp 二.参数讲解 ignore  :关闭所有的 NT ...

  4. Fragment 事务 回退栈

    一些相关API 1.Fragment常用的三个类: android.app.Fragment 定义android.app.FragmentManager 用于在Activity中操作Fragmenta ...

  5. OLEDB 连接EXCEL的连接字符串IMEX的问题(Oledb)

    今天碰到一个问题需要想EXCEL表中写数据,折腾了好久才发现是IMEX惹得祸,所以记录下提醒自己,也希望大家不要出同样的错. 碰到问题:使用语句 "insert into [Sheet1$] ...

  6. DHCP租约时间工作原理

    问题:    很多用户在使用路由器的DHCP服务器过程中都有一个疑问,DHCP有个设置项目是设置DHCP地址的租约时间,如果设置的比较短,是否会出现租约时间到了以后会重新去获取ip地址,造成用户断网? ...

  7. 13 hbase连接

    Configuration conf=new Configuration(); String zookeeper=""; String clientport="; Str ...

  8. [转]C++智能指针的创建

    zero 坐在餐桌前,机械的重复“夹菜 -> 咀嚼 -> 吞咽”的动作序列,脸上用无形的大字写着:我心不在焉.在他的对面坐着 Solmyr ,慢条斯理的吃着他那份午餐,维持着他一贯很有修养 ...

  9. 使用2to3转换python代码

    如果要把python2编译器下的代码转换升级到python3编译器,可以使用python自带的 2to3工具进行转化: windows下转化: doc 命令窗口: >> python  C ...

  10. 安装.net framework 4.0失败,出现HRESULT 0xc8000222错误代码

    安装了一上午的.net framework 4.0,各种失败,查了好多答案,各种不靠谱,最后终于找到答案了 和Windows Update有关系,给目录名重命名一下再次安装,即安装成功了! 方法: 1 ...