new BigDecimal(0.01) 与 new BigDecimal(String.valueOf(0.01))的区别 (转)
转自: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))的区别 (转)的更多相关文章
- String.valueOf()和toString()的区别
1.String.valueOf(): Object obj=null; String str=""; str=String.valueOf(obj); //str=obj.toS ...
- 这种写法用过没:string.Format("{0,-10}", 8)
1 2 3 4 var s1 = string.Format("{0,-10}", 8); var s2 = string.Format("{0,10}", 8 ...
- Java的String.valueOf 转换 与、空串+类型变量转换与封装类(Integer)的toString方式转换比较。
1.空串+类型变量方式转换 int i=20; String s=""+i; 这种方式实际上经过了两个步骤,首先进行了i.ToString()把 i 转换为 字符串,然后再进行加法 ...
- try { var mergeFilePath = string.Format("{0}mergepdf.pdf", tempDownDir); PDFPrintHelper.MergePDFFile(pdfList, mergeFi
winform 按顺序连续打印多个PDF文件 关于PDF打印的问题,前面有篇文章(点这里查看)也叙述过,今天来谈谈另外一种方法 其实方法很简单,因为需要把多个PDF文档按顺序连续打印,为此我们为什 ...
- 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 ...
- Java中string.equalsIgnoreCase("0")与"0".equalsIgnoreCase(string)的区别:
string.equalsIgnoreCase("0"):如果string为null,会抛出java.lang.NullPointerException异常. "0&qu ...
- 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 ...
- 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 ...
- YII报错笔记:<pre>PHP Notice 'yii\base\ErrorException' with message 'Uninitialized string offset: 0' in /my/test/project/iot/vendor/yiisoft/yii2/base/Model.php:778
YII常见报错笔记 报错返回的代码如下: <pre>PHP Notice 'yii\base\ErrorException' with message 'Uninitialized str ...
随机推荐
- 【Python】【爬虫】如何学习Python爬虫?
如何学习Python爬虫[入门篇]? 路人甲 1 年前 想写这么一篇文章,但是知乎社区爬虫大神很多,光是整理他们的答案就够我这篇文章的内容了.对于我个人来说我更喜欢那种非常实用的教程,这种教程对于想直 ...
- mysql 约束条件 外键 forigen key 介绍
外键 forigen key作用 :建立表之间的关系 什么是外键 员工信息表有这些字段:id号 姓名 性别 员工所在部门名 部门描述信息 公司有3个部门,但是有1个亿的员工,那意味着 员工所对应的部 ...
- mysql 数据操作 单表查询 简单查询 避免重复DISTINCT
创建数据库company create database company charset=utf8; use company; company.employee 员工id id int 姓名 emp_ ...
- JavaScript类库汇总
日期处理Moment.js http://momentjs.cn/ http://momentjs.com/ nodejslinq,jslinq http://jslinq.codepl ...
- angry_birds_again_and_again(2014年山东省第五届ACM大学生程序设计竞赛A题)
http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2877 题目描述 The problems ca ...
- sdut AOE网上的关键路径(spfa+前向星)
http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2498&cid=1304 题目描述 一个无环的有向图称为无环图(Directed Acyc ...
- Sql Server CPU 性能排查及优化的相关 Sql
Sql Server CPU 性能排查及优化的相关 Sql 语句,非常好的SQL语句,记录于此: --Begin Cpu 分析优化的相关 Sql --使用DMV来分析SQL Server启动以来累计使 ...
- C# 多线程编程第一步——理解多线程
一.进程.线程及多线程的概念 什么是多线程呢?不理解. 那什么是线程呢?说到线程就不得不说说进程.我在网上搜索也搜索了一些资料,大部分所说的进程其实是很抽象的东西.通俗的来讲,进程就是一个应用程序开始 ...
- 【OpenCV学习笔记】三十、轮廓特征属性及应用(七)—位置关系及轮廓匹配
http://blog.csdn.net/abc8730866/article/details/69219992 轮廓特征属性及应用(七)—位置关系及轮廓匹配 1.计算点与轮廓的距离及位置关系——po ...
- MySQL测试工具之-tpcc
首先安装tpcc 官网地址:https://github.com/Percona-Lab/tpcc-mysql [root@test3 src]# unzip tpcc-mysql-master.zi ...