背景:

在对数值做一些计算的时候,往往我们需要控制计算结果的精度,所以会使用到DecimalFormat类来将数值格式化成字符串。在最近测试中,突然注意到默认使用DecimalFormat进行格式化时,并非我们一般认识上的四舍五入,而是一种诡异的舍入——(1)5以下舍去(2)5以上舍入(3)若前一位是奇数,5就舍入(4)如前一位是偶数,5就舍去

遇到这样的统计结论,没有理论的支持,我们总是感到很迷茫,所以我仔细查阅了DecimalFormat相关API,终于找到了答案。

分析:

在DecimalFormat API中有这样一段:

舍入

DecimalFormat 提供 RoundingMode 中定义的舍入模式进行格式化。默认情况下,它使用RoundingMode.HALF_EVEN

这句话指出了舍入模式有多种类型,而DecimalFormat默认采用了RoundingMode.HALF_EVEN这种类型,接下来,我们就一起看看,到底存在哪些舍入类型吧

RoundingMode介绍:

RoundingMode是一个枚举类,有一下几个常量:UP,DOWN,CEILING,FLOOR,HALF_UP,HALF_DOWN,HALF_EVEN,UNNECESSARY


UP
public static final RoundingMode UP
远离零方向舍入的舍入模式。始终对非零舍弃部分前面的数字加 1。注意,此舍入模式始终不会减少计算值的绝对值。

示例:

输入数字 使用 UP 舍入模式
将输入数字舍入为一位数
5.5 6
2.5 3
1.6 2
1.1 2
1.0 1
-1.0 -1
-1.1 -2
-1.6 -2
-2.5 -3
-5.5 -6

DOWN
public static final RoundingMode DOWN
向零方向舍入的舍入模式。从不对舍弃部分前面的数字加 1(即截尾)。注意,此舍入模式始终不会增加计算值的绝对值。

示例:

输入数字 使用 DOWN 舍入模式
将输入数字舍入为一位数
5.5 5
2.5 2
1.6 1
1.1 1
1.0 1
-1.0 -1
-1.1 -1
-1.6 -1
-2.5 -2
-5.5 -5

CEILING
public static final RoundingMode CEILING
向正无限大方向舍入的舍入模式。如果结果为正,则舍入行为类似于 RoundingMode.UP;如果结果为负,则舍入行为类似于 RoundingMode.DOWN。注意,此舍入模式始终不会减少计算值。

示例:

输入数字 使用 CEILING 舍入模式
将输入数字舍入为一位数
5.5 6
2.5 3
1.6 2
1.1 2
1.0 1
-1.0 -1
-1.1 -1
-1.6 -1
-2.5 -2
-5.5 -5

FLOOR
public static final RoundingMode FLOOR
向负无限大方向舍入的舍入模式。如果结果为正,则舍入行为类似于 RoundingMode.DOWN;如果结果为负,则舍入行为类似于RoundingMode.UP。注意,此舍入模式始终不会增加计算值。

示例:

输入数字 使用 FLOOR 舍入模式
将输入数字舍入为一位数
5.5 5
2.5 2
1.6 1
1.1 1
1.0 1
-1.0 -1
-1.1 -2
-1.6 -2
-2.5 -3
-5.5 -6

HALF_UP
public static final RoundingMode HALF_UP
向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向上舍入。如果被舍弃部分 >= 0.5,则舍入行为同 RoundingMode.UP;否则舍入行为同RoundingMode.DOWN。注意,此舍入模式就是通常学校里讲的四舍五入。

示例:

输入数字 使用 HALF_UP 舍入模式
将输入数字舍入为一位数
5.5 6
2.5 3
1.6 2
1.1 1
1.0 1
-1.0 -1
-1.1 -1
-1.6 -2
-2.5 -3
-5.5 -6

HALF_DOWN
public static final RoundingMode HALF_DOWN
向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向下舍入。如果被舍弃部分 > 0.5,则舍入行为同 RoundingMode.UP;否则舍入行为同RoundingMode.DOWN

示例:

输入数字 使用 HALF_DOWN 舍入模式
将输入数字舍入为一位数
5.5 5
2.5 2
1.6 2
1.1 1
1.0 1
-1.0 -1
-1.1 -1
-1.6 -2
-2.5 -2
-5.5 -5

HALF_EVEN
public static final RoundingMode HALF_EVEN
向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。如果舍弃部分左边的数字为奇数,则舍入行为同RoundingMode.HALF_UP;如果为偶数,则舍入行为同RoundingMode.HALF_DOWN。注意,在重复进行一系列计算时,此舍入模式可以在统计上将累加错误减到最小。此舍入模式也称为“银行家舍入法”,主要在美国使用。此舍入模式类似于 Java 中对float 和double 算法使用的舍入策略。

示例:

输入数字 使用 HALF_EVEN 舍入模式
将输入数字舍入为一位数
5.5 6
2.5 2
1.6 2
1.1 1
1.0 1
-1.0 -1
-1.1 -1
-1.6 -2
-2.5 -2
-5.5 -6

UNNECESSARY
public static final RoundingMode UNNECESSARY
用于断言请求的操作具有精确结果的舍入模式,因此不需要舍入。如果对生成精确结果的操作指定此舍入模式,则抛出 ArithmeticException

示例:

输入数字 使用 UNNECESSARY 舍入模式
将输入数字舍入为一位数
5.5 抛出 ArithmeticException
2.5 抛出 ArithmeticException
1.6 抛出 ArithmeticException
1.1 抛出 ArithmeticException
1.0 1
-1.0 -1
-1.1 抛出 ArithmeticException
-1.6 抛出 ArithmeticException
-2.5 抛出 ArithmeticException
-5.5 抛出 ArithmeticException


【Java实战】DecimalFormat对数值格式化的舍入问题——RoundingMode的更多相关文章

  1. 数值格式化 NumberFormat DecimalFormat RoundingMode

    NumberFormat [简介] java.text.NumberFormat extends java.text.Format extends java.lang.Object 实现的接口:Ser ...

  2. 数值格式化 NumberFormat、 DecimalFormat、 RoundingMode

    NumberFormat [简介] java.text.NumberFormat extends java.text.Format extends java.lang.Object 实现的接口:Ser ...

  3. java小数位-DecimalFormat(转)

    转载:http://blog.sina.com.cn/s/blog_93daad410101159s.html java格式化数字DecimalFormat 在输出数字时,有时需要给数字配上单位,有时 ...

  4. Java中 DecimalFormat 用法详解

    我们经常要将数字进行格式化,比如取2位小数,这是最常见的.Java 提供DecimalFormat类,帮你用最快的速度将数字格式化为你需要的样子.下面是一个例子: import java.text.D ...

  5. HighCharts日期及数值格式化

    1.函数原型   1 dateFormat(Stringformat,[Numbertime],[Booleancapitalize])::String 2.说明 格式化JavaScript 时间(也 ...

  6. js 数值格式化函数

    function ForDight(Dight,How){ ,How))/Math.pow(,How); return Dight; } //ForDight(Dight,How):数值格式化函数; ...

  7. 「小程序JAVA实战」springboot的后台搭建(31)

    转自:https://idig8.com/2018/08/29/xiaochengxujavashizhanspringbootdehoutaidajian31/ 根据下面的图,我们来建立下对应的sp ...

  8. Java实战:教你如何进行数据库分库分表

    摘要:本文通过实际案例,说明如何按日期来对订单数据进行水平分库和分表,实现数据的分布式查询和操作. 本文分享自华为云社区<数据库分库分表Java实战经验总结 丨[绽放吧!数据库]>,作者: ...

  9. java成神之——数值操作BigDecimal,BigInteger,Random,SecureRandom

    数值操作 数值新特性 包装类 浮点 BigDecimal BigInteger 数值本地化 随机数 假随机数 真随机数 播种 结语 数值操作 数值新特性 123_456 等价于 123456,增加可读 ...

随机推荐

  1. 分析Ubuntu18.04启动后的各种任务

    jello@jello:~$ ps -A  PID TTY          TIME CMD    1 ?        00:00:02 systemd    由idle进程(进程号为0的进程,那 ...

  2. iOS开发进阶 - 基于PhotoKit的图片选择器

    移动端访问不佳,请访问我的个人博客 很早之前就用OC把代码写完了并用在项目中了,一直没时间整理,现在用swift重写一份,并且更加详细的来了解这个Photos框架,下面是我集合苹果官方文档和其他大神的 ...

  3. Servlet3.0与Spring

    servlet   filter  listener  web.xml DispatcherServlet  web.xml 后期 servlet3.0我们去除web.xml 通过注解方式 同时需要s ...

  4. poj3299 - Humidex

    2017-08-31 19:08:25 writer:pprp 水题: 没有技术含量hhh 但是,还是花了很长时间,以后水题也是很有必要练习的 /* @theme:poj 3299 @writer:p ...

  5. PHP Fatal error: Call to undefined function imagecreatetruecolor()

    是因为没有安装gd apt-get install libgd2-xpm-dev* apt-get install php5-gd

  6. 洛谷P3601 签到题

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  7. ubuntu mac terminal install software

    http-server // ubuntu sudo npm install http-server -g npm node.js yarn

  8. 【转】学习Python的19个资源

    原文链接:[译]学习Python编程的19个资源 用Python编写代码一点都不难,事实上它一直被赞誉为最容易学的编程语言.如果你准备学习web开发, Python是一个不错的开始,甚至想做游戏的话, ...

  9. 深入理解AUC

    https://tracholar.github.io/machine-learning/2018/01/26/auc.html 我觉得作者写的很不错

  10. [java]Stream API——map和flatMap的区别

    map方法 map的含义为映射.是指对于Stream中包含的每一个元素使用给定的转换函数进行转换. map传入的Lambda表达式必须是Function实例,参数可以为任意类型,而其返回值也是任性类型 ...