一、分析
在许多数学计算的场景中,会用到近似取值的计算方法。常用的近似取值有四舍五入。
但是在某些金融行业或特殊场景中,四舍五入的方式就不太适宜。目前Java支持一下其中舍入方式:
-
ROUND_UP:远离零方向舍入,向远离0的方向舍入,也就是说,向绝对值最大的方向舍入,只要舍弃位非0即进位。
-
ROUND_DOWN:趋向零方向的舍入,向0方向靠拢,也就是说,向绝对值最小的方向输入。注意,所有的位都舍弃不存在进位的情况。
-
ROUND_CEILING:向正无穷方向舍入,向正最大方向靠拢,如果是正数,舍入行为类似于ROUND_UP;如果是负数,则舍入行为类似于ROUND_DOWN。注意,Math.round方法使用的即此模式。
-
ROUND_FLOOR:向负无穷方向舍入,向负无穷方向靠拢,如果是正数,则舍入行为类似于ROUND_DOWN;如果是负数,则舍入行为类似于ROUND_UP。
-
HALF_UP:最近数字舍入(5进),这就是我们最经典的四舍五入模式。
-
HALF_DOWN:最近数字舍入(5舍),在四舍五入中,5是进位的,而在HALF_DOWN中却是舍弃不进位。
-
HALF_EVEN:银行家算法,四舍六入五考虑,五后非零就进一,五后为零看奇偶,五前为偶应舍去,五前为奇要进一。
二、场景
使用Math.round来指定精度的整数或小数:
由于Math.round采用的舍入规则是正无穷方向舍入。所以输出结果为:
10.5近似值:11
-10.5近似值:-10
但是在银行计算利息的场景下,适应四舍五入计算利息就会出现如下情况:
按照概率计算克制,被舍入的数字均匀的分布在0到9之间,下面以10笔存款利息计算作为模型,以银行家的身份来思考这个算法:
-
四舍:舍弃的数值:0.000、0.001、0.002、0.003、0.004,因为是舍弃的,对于银行家来说,就不用付给储户利息了,那每舍弃一个数字就会赚取相应的金额:0.000、0.001、0.002、0.003、0.004。
-
五入:进位的数值:0.005、0.006、0.007、0.008、0.009,因为是进位,对于银行家来说,每进一位就会多付款给储户,也就是亏损了,那亏损的部分就是对应的10进制补数:0.005、0.004、0.003、0.002、0.001。
因为舍弃和进位的数字在0到9之间是均匀分布的,所以对于银行家来说,每10笔存款利息因采用四舍五入而获得的盈利是:
0.000+0.001+0.002+0.003+0.004-0.005-0.004-0.003-0.002-0.001=-0.005。
也就是说没10笔利息的计算中,就损失了0.005元,每笔利息计算损失0.0005元。对于一家银行(上亿储户)来说,这个误差造成的损失也不可小视觉。
这个误差是由美国的银行家发现的,所以提供出了一个修正算法,叫做银行家舍入的近似算法,其规则如下:
-
舍去的位数小于5时,直接舍去;
-
舍去的位数大于等于6时,进位后舍去;
-
当舍去的数值等于5时,分两种情况:
-
5后面还有其它数字(非0),则进位后舍去;
-
若5后面是0(即5是最后一个数字),则根据5前一位数的奇偶性来判断是否需要进位,奇数进位,偶数舍去。
-
以上规则汇总成一句话:四舍六入考虑五,五后非零就进一,五后为零看奇偶,五前为偶应舍去,五前为奇要进一。
在Java5以上的版本中,使用银行家的舍入算法非常简单,直接使用RoundingMode类,提供Round模式即可,示例代码如下:
三、建议
根据不同的场景,慎重选择不同的舍入模式,以提高项目的精准度,减少算法损失。在大量与货币数字交互的项目中,一定要选择好近似的计算模式,尽量减少因算法不同而造成的损失。
相关推荐
### PHP的十个不容忽视的问题详解 #### 一、PHP的本质:解释性语言还是编译语言? 根据提供的部分内容,我们可以了解到**PHP**本质上并不是一个简单的解释性语言,而是介于解释性和编译性之间的语言。这一特点让...
### Java语言编码规范详解 #### 一、引言 在软件开发过程中,编码规范的重要性不容忽视。据统计,软件在其整个生命周期中的维护成本大约占...同时,这也为团队协作提供了统一的标准,有助于提高开发效率和代码质量。
这个库在Java 5环境下运行,为开发者提供了丰富的功能,尽管它可能并不广为人知,但其在特定场景下的实用性不容忽视。本文将详细介绍该库的源码和jar文件,帮助你深入理解并充分利用这个工具。 首先,让我们来了解...
JUnit和Mockito等工具可以帮助进行测试驱动开发,确保代码质量。 7. **文档与API**:高质量的API文档是公共资源模块的关键组成部分。Javadoc是一种用于生成API文档的工具,通过在代码中添加特定注释,可以生成易于...
《阿里巴巴Java开发手册》是Java开发者的一份重要参考资料,它由阿里巴巴集团官方发布,旨在提供一套规范化的编程标准,帮助...手册中的每一个细节都是经验的结晶,对于任何Java开发者来说,都是一份不容忽视的指南。
9. **安全性考虑**:Web应用安全不容忽视,可能涉及的身份验证、授权、防止SQL注入和XSS攻击等措施,可以通过Spring Security等框架实现。 10. **文档记录**:良好的文档记录是项目成功的关键。报告中应包括系统...
- **代码质量**:反编译的代码通常不完全等同于原始源代码,可能会丢失注释、变量名和原始格式。 - **混淆的代码**:如果原始代码经过混淆,反编译后的代码可能难以理解和阅读。 在使用Java反编译工具时,理解其...
《Java开发手册(阿里内部版)》是阿里巴巴集团为内部开发者提供的一份详尽的编程规范和最佳实践指南,旨在提升代码质量、提高开发效率、确保系统稳定性。这份手册不仅适用于后端开发工程师,同样对后端架构师具有...
8. **安全性**:网络安全不容忽视,加密算法(如SSL/TLS)、认证授权机制、防止攻击策略(如XSS、CSRF防护)都是系统设计时需要考虑的安全措施。 9. **测试与调试**:单元测试、集成测试是保证软件质量的重要手段,...
### Java编码规范详解 ...综上所述,《Java编码规范》为Java开发者提供了一套完整的编码指南,旨在提高代码质量、可读性和可维护性。遵循这些规范不仅有助于个人技能的提升,也有利于团队协作和项目的长期发展。
8. **Web安全**:包括身份验证、授权、防止SQL注入和XSS攻击等,是Java Web开发中不容忽视的一部分。作者将介绍相关的安全措施和最佳实践。 9. **部署与调试**:如何配置和部署Java Web应用到不同的服务器,以及...
### Java编程规范(华为) #### 1.1 排版 **1.1.1 规则** 1. **程序块缩进** - **规定**: 程序块应采用4个空格的...此外,注释的重要性也不容忽视,它不仅有助于当前项目的开发工作,也为未来的维护提供了便利。
在JAVA编程的世界里,细节...对于JAVA开发者来说,深入理解和熟练运用这些知识点,不仅可以提高编程效率,也能提升代码质量,为公司的项目开发带来显著的优势。持续学习和实践,是成为一名优秀JAVA程序员的必经之路。
Java开发工具包(Java Development Kit,简称JDK)是用于编写和运行Java应用程序的重要软件包。这个特定的压缩文件“jdk-7u79-windows-x64.zip”包含了...同时,readme文件提供了关于安装和使用的重要细节,不容忽视。
云平台的安全性不容忽视,Java的SSL/TLS支持、Spring Security框架等,可能在Cloudxy中扮演重要角色,确保数据传输安全和访问控制。 10. **持续集成与部署(CI/CD)** Cloudxy的开发过程中,可能利用Jenkins、...
电子商务系统的安全性不容忽视,包括防止SQL注入、XSS攻击、CSRF攻击等。Spring Security或Apache Shiro等安全框架可以帮助实现权限控制和认证。 9. **RESTful API** 系统可能会采用RESTful API设计,提供前后端...