我最近在一个项目中开始使用Sonar,并且我得到了关于使用构造函数的PMD规则new BigDecimal(double val).当我阅读java文档时,我发现新的BigDecimal(double val)有些不可预测,我应该使用new BigDecimal(String val)哪个是可预测的.
这是javadoc所说的BigDecimal public BigDecimal(double val):
将double转换为BigDecimal,它是double的二进制浮点值的精确十进制表示形式.返回的BigDecimal的比例是最小值,使得(10scale×val)是整数.
笔记:
这个构造函数的结果可能有点不可预测.有人可能会认为
new BigDecimal(0.1)用Java 编写创建的数字BigDecimal恰好等于0.1(未缩放值为1,等级为1),但它实际上等于0.1000000000000000055511151231257827021181583404541015625.这是因为0.1不能精确地表示为double(或者,就此而言,作为任何有限长度的二进制分数).因此,传递给构造函数的值并不完全等于0.1,尽管有外观.另一方面,String构造函数是完全可预测的:正如人们所期望的那样,write
new BigDecimal("0.1")会创建一个BigDecimal与0.1完全相等的值.因此,通常建议优先使用String构造函数.当必须将double用作a的源时
BigDecimal,请注意此构造函数提供了精确的转换; 它不会产生与使用该Double.toString(double)方法将double转换为String 然后使用BigDecimal(String)构造函数相同的结果 .要获得该结果,请使用静态valueOf(double)方法.
为什么这个构造函数确实存在?心不是new BigDecimal(String val)能有这样的事?我new BigDecimal(double val)什么时候应该使用构造函数?
目前我有这个方法:
static boolean checkDecimalPlaces(double d, int decimalPlaces){
if (d==0) return true;
double multiplier = Math.pow(10, decimalPlaces);
double check = d * multiplier;
check = Math.round(check);
check = check/multiplier;
return (d==check);
}
Run Code Online (Sandbox Code Playgroud)
但是这种方法失败的checkDecmialPlaces(649632196443.4279, 4)原因可能是因为我在基数为2的数字上进行了10次数学运算.
那么如何才能正确完成这项检查呢?
我想到获得double值的字符串表示,然后用regexp检查 - 但这感觉很奇怪.
编辑: 谢谢你的所有答案.在某些情况下,我真的得到了一个双倍,在这些情况下,我实现了以下内容:
private static boolean checkDecimalPlaces(double d, int decimalPlaces) {
if (d == 0) return true;
final double epsilon = Math.pow(10.0, ((decimalPlaces + 1) * -1));
double multiplier = Math.pow(10, decimalPlaces);
double check = d * multiplier;
long checkLong = (long) …Run Code Online (Sandbox Code Playgroud) 要求是检查位数是否小于7位,在这种情况下插入DB,否则不.我尝试了以下解决方案:
第一解决方案
public static void checkNoOfDigitVal(BigDecimal bigDecVal) {
BigInteger digits = bigDecVal.toBigInteger();
BigInteger ten = BigInteger.valueOf(10);
int count = 0;
do {
digits = digits.divide(ten);
count++;
} while (!digits.equals(BigInteger.ZERO));
System.out.println("Number of digits : " + count);
}
Run Code Online (Sandbox Code Playgroud)
第一种解决方案有时可以正常工作,但有时候while循环中的条件不满足,并且它会继续增加计数,导致无穷无尽的计数.
二解决方案:
public static void checkNoOfDigitsVal(BigDecimal bigDecVal) {
String string = bigDecVal.toString();
String[] splitedString = string.split("\\.");
String[] newVal = splitedString[0].split("");
int a = newVal.length - 1;
if (a <= 6) {
System.out.println("correct size insert into DB: " + a);
} else {
System.out.println("Incorrect …Run Code Online (Sandbox Code Playgroud)