恶心的0.5四舍五入问题
时间:2022-04-23
本文章向大家介绍恶心的0.5四舍五入问题,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
四舍五入是财务类应用中常见的需求,按中国人的财务习惯,遇到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的条件。
当然,这是权宜之计,如果大家有更好的通用方法,欢迎指正。
- ExtJs学习笔记(14)_Column布局
- 高级盲注—floor,rand,group by报错注入
- 刷脸注册、试装、支付……仅靠一张脸就能买买买的时尚店开业了
- JavaScript引用类型之Array数组之强大的splice()方法
- Linux快速入门03-系统管理
- JavaScript引用类型之Array数组的concat()和push()方法的区别
- JavaScript引用类型之Array数组的排序方法
- Linux快速入门02-文件系统管理
- JavaScript引用类型之Array数组的toString()和valueof()方法的区别
- Linux快速入门04-扩展知识
- JavaScript引用类型之Array数组的拼接方法-concat()和截取方法-slice()
- JavaScript引用类型之Array数组的拼接方法-concat()和截取方法-slice()
- 比特币在2017全球新闻谷歌搜索中排名第二,韩国政府聚焦比特币市场诈骗和假冒交易所
- ExtJs学习笔记(13)_Card布局
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 视频高速上云网关/网络穿透EasyNTS智能组网服务平台ini配置文件丢失如何处理?
- 结构与算法(05):二叉树与多叉树
- 树莓派综合项目2:智能小车(二)tkinter图形界面控制
- 虚拟机系列 | JVM运行时数据区
- 虚拟机系列 | 执行引擎和垃圾回收
- 在Linux系统中编译ARM版EasyNTS上云网关服务报undefined错误的解决方案
- 从全备中恢复单库或单表,小心有坑!
- Zookeeper安装以及常用操作
- Codeforces Round 671 (Div. 2) A-D
- 程序中并没有走缓存,为什么执行时间短了
- ES 常用Linux查询命令汇总
- PostgreSql 怎么获取数据库中关键系统信息(一)
- 树莓派基础实验36:通用串口通信实验
- PIMPL:休想窥探我的隐私!
- 树莓派基础实验37:pyserial模块通信实验