如何使用BigDecimal.ROUND_HALF_UP将0.745舍入到0.75?

ali*_*ane 45 java rounding bigdecimal

我试过以下,

   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 ????????????  
Run Code Online (Sandbox Code Playgroud)

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

Aug*_*sto 89

永远不要从浮点数或双精度数构造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
}
Run Code Online (Sandbox Code Playgroud)

  • 如果使用`BigDecimal.valueOf(double)`,静态工厂方法优于构造函数(在javadocs中注明),这也可以正常工作而不需要字符串.使用`BigDecimal bdTest = BigDecimal.valueOf(1.745); BigDecimal bdTest1 = BigDecimal.valueOf(0.745);`给出相同的结果(0.75) (10认同)
  • @JoshuaGoldberg:“BigDecimal.valueOf(double)”并不是构建 BigDecimal 的首选方式。这是将双精度数转换为 BigDecimal 的首选方法。字符串构造函数是构造 BigDecimal 的首选方式。根据文档:“通常建议优先使用 String 构造函数而不是 [双构造函数]” (3认同)

ass*_*ias 11

double doubleVal = 1.745;
double doubleVal1 = 0.745;
System.out.println(new BigDecimal(doubleVal));
System.out.println(new BigDecimal(doubleVal1));
Run Code Online (Sandbox Code Playgroud)

输出:

1.74500000000000010658141036401502788066864013671875
0.74499999999999999555910790149937383830547332763671875
Run Code Online (Sandbox Code Playgroud)

这显示了两个双打的实际价值,并解释了你得到的结果.正如其他人所指出的,不要使用双构造函数(除了你想要看到double的实际值的特定情况).

更多关于双精度:


小智 10

用BigDecimal.valueOf(double d)而不是new BigDecimal(double d).最后一个有float和double的精度错误.