我尝试了以下内容,
double doubleVal = 1.745;
double doubleVal1 = 0.745;
BigDecimal bdTest = new BigDecimal( doubleVal);
BigDecimal bdTest1 = new BigDecimal( doubleVal1 );
bdTest = bdTest.setScale(2, BigDecimal.ROUND_HALF_UP);
bdTest1 = bdTest1.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("bdTest:"+bdTest); //1.75
System.out.println("bdTest1:"+bdTest1);//0.74 problemmmm ????????????
但得到了奇怪的结果。为什么呢?
答案 0 :(得分:82)
永远不要从浮点数或双精度数构造BigDecimals。从int或字符串构造它们。浮动精度和双倍精度。
此代码按预期工作(我只是将类型从double更改为String):
public static void main(String[] args) {
String doubleVal = "1.745";
String doubleVal1 = "0.745";
BigDecimal bdTest = new BigDecimal( doubleVal);
BigDecimal bdTest1 = new BigDecimal( doubleVal1 );
bdTest = bdTest.setScale(2, BigDecimal.ROUND_HALF_UP);
bdTest1 = bdTest1.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("bdTest:"+bdTest); //1.75
System.out.println("bdTest1:"+bdTest1);//0.75, no problem
}
答案 1 :(得分:11)
double doubleVal = 1.745;
double doubleVal1 = 0.745;
System.out.println(new BigDecimal(doubleVal));
System.out.println(new BigDecimal(doubleVal1));
输出:
1.74500000000000010658141036401502788066864013671875
0.74499999999999999555910790149937383830547332763671875
显示两个双打的实际价值,并说明你得到的结果。正如其他人所指出的,不要使用双构造函数(除了你想要看到double的实际值的特定情况)。
有关双精度的更多信息:
答案 2 :(得分:10)
使用BigDecimal.valueOf(double d)
代替new BigDecimal(double d)
。最后一个有float和double的精度错误。
答案 3 :(得分:2)
这可能会给你一个关于出了什么问题的提示。
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
BigDecimal bdTest = new BigDecimal(0.745);
BigDecimal bdTest1 = new BigDecimal("0.745");
bdTest = bdTest.setScale(2, BigDecimal.ROUND_HALF_UP);
bdTest1 = bdTest1.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("bdTest:" + bdTest);
System.out.println("bdTest1:" + bdTest1);
}
}
问题是,您的输入(double x=0.745;
)不能完全代表0.745。它实际上节省了略低的价值。对于BigDecimals
,这已经低于0.745,所以它向下舍入......
尽量不要使用BigDecimal(double/float)
构造函数。
答案 4 :(得分:2)
为了您的兴趣,请使用double
double doubleVal = 1.745;
double doubleVal2 = 0.745;
doubleVal = Math.round(doubleVal * 100 + 0.005) / 100.0;
doubleVal2 = Math.round(doubleVal2 * 100 + 0.005) / 100.0;
System.out.println("bdTest: " + doubleVal); //1.75
System.out.println("bdTest1: " + doubleVal2);//0.75
或只是
double doubleVal = 1.745;
double doubleVal2 = 0.745;
System.out.printf("bdTest: %.2f%n", doubleVal);
System.out.printf("bdTest1: %.2f%n", doubleVal2);
都打印
bdTest: 1.75
bdTest1: 0.75
我更喜欢让代码尽可能简单。 ;)
正如@mshutov所说,你需要再添加一点以确保半值总是向上舍入。这是因为像265.335
这样的数字比它们出现的要少一些。
答案 5 :(得分:0)
可用各种选项,例如:
Double d= 123.12;
BigDecimal b = new BigDecimal(d, MathContext.DECIMAL64); // b = 123.1200000
b = b.setScale(2, BigDecimal.ROUND_HALF_UP); // b = 123.12
BigDecimal b1 =new BigDecimal(collectionFileData.getAmount(), MathContext.DECIMAL64).setScale(2, BigDecimal.ROUND_HALF_UP) // b1= 123.12
d = (double) Math.round(d * 100) / 100;
BigDecimal b2 = new BigDecimal(d.toString()); // b2= 123.12