java中的BigDecimal关于四舍五入不正确的问题

网上会有下面的问题

BigDecimal a = new BigDecimal(12.555);
System.out.println(a);
System.out.println("原--12.555---------处理结果-->>"+a.setScale(2,BigDecimal.ROUND_HALF_UP));
BigDecimal b = new BigDecimal(12.5550000);
System.out.println(b);
System.out.println("原--12.5550000-----处理结果-->>"+b.setScale(2,BigDecimal.ROUND_HALF_UP));
BigDecimal c = new BigDecimal(12.55500001);
System.out.println(c);
System.out.println("原--12.55500001----处理结果-->>"+c.setScale(2,BigDecimal.ROUND_HALF_UP));

打印结果

12.55499999999999971578290569595992565155029296875
原–12.555---------处理结果–>>12.55
12.55499999999999971578290569595992565155029296875
原–12.5550000-----处理结果–>>12.55
12.5550000100000005431866156868636608123779296875
原–12.55500001----处理结果–>>12.56

首先:java中小数属于浮点型(默认为double)
new BigDecimal(double)参数类型为double的构造方法的结果有一定的不可预知性
首先得从计算机本身去讨论这个问题。我们知道,计算机并不能识别除了二进制数据以外的任何数据。无论我们使用何种编程语言,在何种编译环境下工作,都要先 把源程序翻译成二进制的机器码后才能被计算机识别。以上面提到的情况为例,我们源程序里的2.4是十进制的,计算机不能直接识别,要先编译成二进制。但问 题来了,2.4的二进制表示并非是精确的2.4,反而最为接近的二进制表示是2.3999999999999999。原因在于浮点数由两部分组成:指数和尾数,这点如果知道怎样进行浮点数的二进制与十进制转换,应该是不难理解的。如果在这个转换的过程中,浮点数参与了计算,那么转换的过程就会变得不可预 知,并且变得不可逆。我们有理由相信,就是在这个过程中,发生了精度的丢失。而至于为什么有些浮点计算会得到准确的结果,应该也是碰巧那个计算的二进制与 十进制之间能够准确转换。而当输出单个浮点型数据的时候,可以正确输出,如
1
2
double d = 2.4;
System.out.println(d);
输出的是2.4,而不是2.3999999999999999。也就是说,不进行浮点计算的时候,在十进制里浮点数能正确显示。这更印证了我以上的想法,即如果浮点数参与了计算,那么浮点数二进制与十进制间的转换过程就会变得不可预知,并且变得不可逆。
事实上,浮点数并不适合用于精确计算,而适合进行科学计算。这里有一个小知识:既然float和double型用来表示带有小数点的数,那为什么我们不称 它们为“小数”或者“实数”,要叫浮点数呢?因为这些数都以科学计数法的形式存储。当一个数如50.534,转换成科学计数法的形式为5.053e1,它 的小数点移动到了一个新的位置(即浮动了)。可见,浮点数本来就是用于科学计算的

String 构造方法是完全可预知的:写入 newBigDecimal(“0.1”) 将创建一个 BigDecimal,它正好等于预期的 0.1。因此,比较而言, 通常建议优先使用String构造方法

保留到整数位是四舍五入
BigDecimal a = new BigDecimal(12.5);
//System.out.println(a);
System.out.println("原--12.5---------处理结果-->>"+a.setScale(0,BigDecimal.ROUND_HALF_UP)+"--------四舍五入");
BigDecimal b = new BigDecimal(12.49);
//System.out.println(b);
System.out.println("原--12.49-----处理结果-->>"+b.setScale(0,BigDecimal.ROUND_HALF_UP)+"--------四舍五入");
BigDecimal c = new BigDecimal(12.51);
//System.out.println(c);
System.out.println("原--12.51----处理结果-->>"+c.setScale(0,BigDecimal.ROUND_HALF_UP)+"--------四舍五入");

打印结果
原–12.5---------处理结果–>>13--------四舍五入
原–12.49-----处理结果–>>12--------四舍五入
原–12.51----处理结果–>>13--------四舍五入

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值