恶心的0.5四舍五入问题

简介: 四舍五入是财务类应用中常见的需求,按中国人的财务习惯,遇到0.5统一向上进位,但是c#与java中默认的却不是这样。 见c#代码: 1 static void Main(string[] args) 2 { 3 Decimal d = 301353.

四舍五入是财务类应用中常见的需求,按中国人的财务习惯,遇到0.5统一向上进位,但是c#与java中默认的却不是这样。

见c#代码:

1         static void Main(string[] args)
2         {
3             Decimal d = 301353.05M;
4             Console.WriteLine(d);//301353.05
5             Console.WriteLine(Math.Round(d, 1));//301353.0
6             Console.WriteLine(Math.Round(d, 1, MidpointRounding.AwayFromZero));//301353.1
7 
8             Console.ReadKey();
9         }

默认情况下,如果要舍弃的位置上,正好值是5,系统会看前一位是奇数还是偶数,如果是偶数,则丢弃最后1位,即上面代码行5,输出的结果为 301353.0,这不符合国人的习惯,所以要人为指定第3个参数"MidpointRounding.AwayFromZero"

 

java中也提出了类似的做法,但是有“缺陷”

1     @Test
2     public void testScale(){
3         double d = 301353.05;
4         BigDecimal decimal = new BigDecimal(d);
5         System.out.println(decimal);//301353.0499999999883584678173065185546875
6         System.out.println(decimal.setScale(1, RoundingMode.HALF_UP));//301353.0
7     }

类似的,在设置精度时,可以指定一个额外的参数RoundingMode.HALF_UP,表示如果要舍弃的这一位正好是5,则向上进位,代码看似没有问题,但是输出值却是301353.0

原因在于BigDecimal在计算机内部的存储值为"301353.0499999999883584678173065185546875",即小数点第2位是4,上面的代码要求精度到1位,所以代码执行时,只看第2个小数位,其值为4,没有到HALF的标准,因此直接扔掉

 

改进方法:

1     @Test
2     public void testScale(){
3         double d = 301353.05 + 0.0000000001;
4         BigDecimal decimal = new BigDecimal(d);
5         System.out.println(decimal);//301353.0500000001047737896442413330078125
6         System.out.println(decimal.setScale(1, RoundingMode.HALF_UP));//301353.1
7     }

在满足财务精度的前提下,将要处理的数字加1个微小的偏移量,这样计算机内部存储时,值变成301353.0500000001047737896442413330078125,这样小数位第2位变成了5,满足了HALF_UP的条件。

 

当然,这是权宜之计,如果大家有更好的通用方法,欢迎指正。

目录
相关文章
|
JavaScript 前端开发
JS浮点数精度问题及高精度小数运算:BigNumber解决方案
JS浮点数精度问题及高精度小数运算:BigNumber解决方案
1432 0
|
缓存
Microsoft Store微软商店更新失败/无法更新应用解决方法
Microsoft Store微软商店更新失败/无法更新应用解决方法
11231 0
|
JavaScript
jQuery的事件
jQuery的事件
192 0
jQuery的事件
|
关系型数据库 MySQL
MySql正则表达式简介及使用
MySql正则表达式简介及使用
236 0
Zp
|
Java
Springboot通过自定义工具类获取bean
Springboot通过自定义工具类获取bean
Zp
440 0
|
弹性计算 运维 安全
【阿里云建站】云服务器竟然能免费送?
不管做什么事情,人们总想着越省力、越高效越好。现在做生意都讲究轻资产,IT领域使用云服务器就是基于这样的原因。
294 0
【阿里云建站】云服务器竟然能免费送?
|
前端开发 JavaScript
巧用 SVG 滤镜还能制作表情包?
巧用 SVG 滤镜还能制作表情包?
404 0
巧用 SVG 滤镜还能制作表情包?
|
存储 Linux Python
回答了一个知乎付费咨询....
的确,PDF、Word作为工作和学习中经常会接触到的文档格式,很难避免与其打交道,今天,就来给大家介绍一下如何使用Python完成常用的PDF、Word编辑功能,再也不用为这项简单的事情付费了!
回答了一个知乎付费咨询....
下一篇
oss云网关配置