转自:http://blog.csdn.net/major1985/article/details/50210293

一般我们使用BigDecimal进行比较精密的计算,我这里计算金额。注意使用double构造器的本质与String构造的本质,避免造成问题。

我这里出现的问题是金额总是多了0.01

问题出现在这段代码:

if(valueDiffDays > ){
logger.info("该账单{}需要缴纳{}天利息",loanBillLogDO.getBillSeqNo(),valueDiffDays);
interestAmt = repayAmt * interestDayRate * valueDiffDays;
loanBillLogDO.setInterestAmt(new BigDecimal(interestAmt).setScale(, RoundingMode.UP)); }

应该是0.80的总是变成0.81,进行断点调试发现interestAmt的值是0.8.

进行测试:

 @Test
public void testBigDecimalMode(){
double dayRate = 0.08;
double amt = ;
int diff = ; double interestAmt = amt*dayRate/*diff;
BigDecimal tInterestAmt = new BigDecimal(interestAmt).setScale( , RoundingMode.UP);
System.out.println(interestAmt);
System.out.println(tInterestAmt); BigDecimal a = new BigDecimal("0.8");
System.out.println(a.setScale(, RoundingMode.UP));
BigDecimal b = new BigDecimal(0.8);
System.out.println(b.setScale( , RoundingMode.UP));
// loanBillLogDO.setInterestAmt(new BigDecimal(interestAmt).setScale(2, RoundingMode.UP));
}

基本确定BigDecimal的double构造存在问题,String构造不存在问题。

api说明:

BigDecimal

public BigDecimal(String val)
将 BigDecimal 的字符串表示形式转换为 BigDecimal。字符串表示形式由可选符号 '+' ( '\u002B') 或 '-' ( '\u002D') 组成,后跟零或多个十进制数字(“整数”)的序列,可以选择后跟一个小数,也可以选择后跟一个指数。
该小数由小数点以及后跟的零或更多十进制数字组成。字符串必须至少包含整数或小数部分中的一个数字。由符号、整数和小数部分组成的数字称为有效位数。 指数由字符 'e'('\u0065') 或 'E' ('\u0045') 以及后跟的一个或多个十进制数字组成。指数的值必须位于 Integer.MAX_VALUE (Integer.MIN_VALUE+) 和 Integer.MAX_VALUE(包括)之间。 更正式地说,以下语法描述了此构造方法接受的字符串: BigDecimalString:
Signopt Significand Exponentopt
Sign:
+
-
Significand:
IntegerPart . FractionPartopt
. FractionPart
IntegerPart
IntegerPart:
Digits
FractionPart:
Digits
Exponent:
ExponentIndicator SignedInteger
ExponentIndicator:
e
E
SignedInteger:
Signopt Digits
Digits:
Digit
Digits Digit
Digit:
Character.isDigit(char) 对其返回 true 的任何字符,如 、、……
返回的 BigDecimal 的标度将是小数部分中的数字位数,如果该字符串不包含小数点,则标度为零,这取决于对指数的调整;如果字符串包含一个指数,则从标度减去该指数。得到的标度值必须位于 Integer.MIN_VALUE 和 Integer.MAX_VALUE(包括)之间。 Character.digit(char, int) 集提供从字符到数字的映射,以转换成基数 。该字符串不能包含任何额外字符(例如,空白)。 示例:
返回的 BigDecimal 的值等于有效位数 × 指数。对于左边的每个字符串,得到的表示形式 [BigInteger, scale] 显示在右边。 "" [,]
"0.00" [,]
"" [,]
"-123" [-,]
"1.23E3" [,-]
"1.23E+3" [,-]
"12.3E+7" [,-]
"12.0" [,]
"12.3" [,]
"0.00123" [,]
"-1.23E-12" [-,]
"1234.5E-4" [,]
"0E+7" [,-]
"-0" [,] 注:对于不是 float、double NaN 和 ±Infinity 的值,此构造方法与 Float.toString(float) 和 Double.toString(double) 返回的值兼容。这通常是将 float 或 double 转换为 BigDecimal 的首选方法,因为它不会遇到 BigDecimal(double) 构造方法的不可预知问题。 参数:
val - BigDecimal 的字符串表示形式。
抛出:
NumberFormatException - 如果 val 不是 BigDecimal 的有效表示形式。

new BigDecimal(0.01) 与 new BigDecimal(String.valueOf(0.01))的区别 (转)的更多相关文章

  1. String.valueOf()和toString()的区别

    1.String.valueOf(): Object obj=null; String str=""; str=String.valueOf(obj); //str=obj.toS ...

  2. 这种写法用过没:string.Format("{0,-10}", 8)

    1 2 3 4 var s1 = string.Format("{0,-10}", 8); var s2 = string.Format("{0,10}", 8 ...

  3. Java的String.valueOf 转换 与、空串+类型变量转换与封装类(Integer)的toString方式转换比较。

    1.空串+类型变量方式转换 int i=20; String s=""+i; 这种方式实际上经过了两个步骤,首先进行了i.ToString()把 i 转换为 字符串,然后再进行加法 ...

  4. try { var mergeFilePath = string.Format("{0}mergepdf.pdf", tempDownDir); PDFPrintHelper.MergePDFFile(pdfList, mergeFi

    winform 按顺序连续打印多个PDF文件   关于PDF打印的问题,前面有篇文章(点这里查看)也叙述过,今天来谈谈另外一种方法 其实方法很简单,因为需要把多个PDF文档按顺序连续打印,为此我们为什 ...

  5. case a.ass_term_unit when '01' then (case a.ass_profit_mode when '0' then round(sum(a.ass_amount*a.ass_annual_rate/365*365*a.ass_term/100) ,2) when '1' then round(sum(a.ass_amount*a.ass_annual_rate/

    --01 年 02 月 03 日 select a.ass_due_date, case a.ass_term_unit when '01' then (case a.ass_profit_mode ...

  6. Java中string.equalsIgnoreCase("0")与"0".equalsIgnoreCase(string)的区别:

    string.equalsIgnoreCase("0"):如果string为null,会抛出java.lang.NullPointerException异常. "0&qu ...

  7. tensorflow models api:ValueError: Tensor conversion requested dtype string for Tensor with dtype float32: 'Tensor("arg0:0", shape=(), dtype=float32, device=/device:CPU:0)'

    tensorflow models api:ValueError: Tensor conversion requested dtype string for Tensor with dtype flo ...

  8. org.apache.tomcat.util.descriptor.web.WebXml.setVersion Unknown version string [4.0]. Default version will be used.报错

    org.apache.tomcat.util.descriptor.web.WebXml.setVersion Unknown version string [4.0]. Default versio ...

  9. YII报错笔记:<pre>PHP Notice &#039;yii\base\ErrorException&#039; with message &#039;Uninitialized string offset: 0&#039; in /my/test/project/iot/vendor/yiisoft/yii2/base/Model.php:778

    YII常见报错笔记 报错返回的代码如下: <pre>PHP Notice 'yii\base\ErrorException' with message 'Uninitialized str ...

随机推荐

  1. xutil3 post 和 get请求

    https://i.cnblogs.com/EditPosts.aspx?postid=7001253 compile 'org.xutils:xutils:3.3.36' 注册xutil3 < ...

  2. Word 2010文档自动生成目录和某页插入页码

    一.Word 2010文档自动生成目录 关于Word文档自动生成目录一直是我身边同学们最为难的地方,尤其是毕业论文,经常因为目录问题,被要求修改,而且每次修改完正文后,目录的内容和页码可能都会发生变化 ...

  3. Hadoop权限认证的执行流程

    Hadoop分布式文件系统实现了一个和POSIX系统类似的文件和目录的权限模型.每个文件和目录有一个所有者(owner)和一个组(group).文件或目录对其所有者.同组的其他用户以及所有其他用户分别 ...

  4. Selenium之firefox浏览器的启动问题及解决

    启动firefox报错如下: rg.openqa.selenium.firefox.NotConnectedException: Unable to connect to host 127.0.0.1 ...

  5. Linux Find命令使用方法举例

    linux命令之find命令使用举例. 在当前目录和子目录下查找文件MyCProgram.c  # find . -name "MyCProgram.c" 查找文件且忽略大小写  ...

  6. django-生成随机验证码

    Python生成随机验证码,需要使用PIL模块. 安装: pip3 install pillow 1   1 pip3 install pillow 基本使用 1.创建图片 from PIL impo ...

  7. king 选 太子

    king 选 太子 时间限制:3000 ms  |  内存限制:65535 KB 难度:1   描述 啊,从前有一个国家.此国兵强马壮,但是国王却身体不好.于是就想挑一位太子出来: 但是问题来了,国王 ...

  8. 【转载】open-falcon部署

    运维监控系统之Open-Falcon   一.Open-Falcon介绍 1.监控系统,可以从运营级别(基本配置即可),以及应用级别(二次开发,通过端口进行日志上报),对服务器.操作系统.中间件.应用 ...

  9. Python3:爬取新浪、网易、今日头条、UC四大网站新闻标题及内容

    Python3:爬取新浪.网易.今日头条.UC四大网站新闻标题及内容 以爬取相应网站的社会新闻内容为例: 一.新浪: 新浪网的新闻比较好爬取,我是用BeautifulSoup直接解析的,它并没有使用J ...

  10. 20155201 2016-2017-2 《Java程序设计》第四周学习总结

    20155201 2016-2017-2 <Java程序设计>第四周学习总结 教材学习内容总结 - 第六章要点: 继承:面向对象中,子类继承父类,避免重复的行为定义.继承基本上就是避免多个 ...