我尝试了以下,

   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 ????????????  

但得到了奇怪的结果。 为什么?

#1楼 票数:103 已采纳

切勿从浮点数或双精度数构造 BigDecimals。 从整数或字符串构造它们。 浮动和加倍松散精度。

此代码按预期工作(我只是将类型从 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
}

#2楼 票数:13

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 构造函数(除了要查看 double 的实际值的特定情况)。

关于双精度的更多信息:

#3楼 票数:10

使用BigDecimal.valueOf(double d)而不是new BigDecimal(double d) 最后一个有浮点和双精度误差。

#4楼 票数:3

这可能会给你一个关于出了什么问题的提示。

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); // prints "bdTest:0.74"
        System.out.println("bdTest1:" + bdTest1); // prints "bdTest:0.75"
    }
}

问题是,您的输入( double x=0.745; )不能准确表示 0.745。 它实际上节省了一个稍低的值。 对于BigDecimals ,这已经低于 0.745,所以它向下取整......

尽量不要使用BigDecimal(double/float)构造函数。

#5楼 票数: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这样的数字比它们显示的要少一些。

#6楼 票数: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



  ask by aliplane translate from so

未解决问题?本站智能推荐:

2回复

BigDecimal.ROUND_HALF_UP和RoundingMode.HALF_UP之间的区别?

下面: 似乎工作。 但是,以下内容返回错误: 错误:
1回复

使用ROUND_HALF_UP的BigDecimal 1.0E + 8/100000000为0

有人可以解释为什么第一行的结果为0?
1回复

BigDecimal使用ROUND_HALF_UP不能取整

我正在创建一个应用程序来计算带有百分比的标记平均值,但是问题是BigDecimal并不总是四舍五入,例如,如果标记平均值为3.85 BigDecimal ROUND_HALF_UP,则小数位数1应该四舍五入为3.9,但显示的平均值为3.8,这种情况仅在某些特定时间发生,有时BigDecimal第
3回复

Java BigDecimal使用String构造函数进行错误,以使用ROUND_HALF_UP进行舍入

我正在尝试实现一个新的等级舍入到BigDecimal类,我得到一个可能的错误,我可能做错了。 下面的代码暴露了我的问题: 我的疑问是,BigDecimal对于double和String构造函数是不同的? 我无法理解这个'bug',至少,我只是用一个简单的字符串concat来“解决
1回复

使用HALF_UP舍入模式舍入时BigDecimal令人惊讶的行为[重复]

这个问题在这里已有答案: 如何使用BigDecimal.ROUND_HALF_UP将0.745舍入到0.75? 5个答案 我正在从0.495的double值创建一个BigDecimal,并使用HALF_UP舍入模式将其打印为两位小数。 这是代码: 我期待
2回复

BigDecimal.ROUND_UP问题

为什么我得到184.84的卖出率? 为什么它在BigDecimal.ROUND_UP中如此操作。 我检查了BigDecimal.ROUND_HALF_EVEN。 工作正常。 但我想知道为什么会这样。
1回复

使用HALF_UP舍入到最接近的值

我想将BigDecimal值舍入到最接近的整数。 我尝试使用此问题中的解决方案Java BigDecimal:四舍五入到最接近的整数值 ,但这对我不起作用。 它可以在以下情况下正常工作: 但是万一失败了 为什么此代码不起作用?
1回复

java中如何判断BigDecimal.round()内部使用哪种舍入方法

我正在使用 BigDecimal 根据所需的有效数字对输入进行舍入,实际输入和所需的有效数字来自 JtextPane。 这是示例代码; 这将导致1230.0 ,这很好。 但它也需要输出是否四舍五入或四舍五入。 有没有办法确定?