浅谈使用DecimalFormat保留小数点的问题
目录
- 1.使用#占位符号,保留一位小数点,没有0的情况
- 2.使用#占位符号,保留一位小数点,有0的情况,不保留0
- 3.使用0占位符号,保留一位小数点,有0的情况,保留0
- 4.使用0占位符号,保留四位小数点,且目标数的位数不够时
- 5.使用#占位符号,保留四位小数点,且目标数的位数不够时
在某些场景下,我们经常要将数字进行格式化,比如取2位小数,或者四舍五入、取整等等,这是最常见的。那么我们应该怎么去实现呢?

Java 提供DecimalFormat类,它可以帮你用最快的速度将数字格式化为你需要的样子。详情请看下面案例列举:
double pi = 3.1415927;//圆周率约等
//取一位整数
System.out.println(new DecimalFormat("0").format(pi));//3
//取一位整数和两位小数
System.out.println(new DecimalFormat("0.00").format(pi));//3.14
//取两位整数和三位小数,整数不足部分以0填补。
System.out.println(new DecimalFormat("00.000").format(pi));//03.142
//取所有整数部分
System.out.println(new DecimalFormat("#").format(pi));//3
//以百分比方式计数,并取两位小数
System.out.println(new DecimalFormat("#.##%").format(pi));//314.16%
long c = 299792458;//光速
//显示为科学计数法,并取五位小数
System.out.println(new DecimalFormat("#.#####E0").format(c));//2.99792E8
//显示为两位整数的科学计数法,并取四位小数
System.out.println(new DecimalFormat("00.####E0").format(c));//29.9792E7
//每三位以逗号进行分隔。
System.out.println(new DecimalFormat(",###").format(c));//299,792,458
//将格式嵌入文本
System.out.println(new DecimalFormat("光速大小为每秒,###米。").format(c));//光速大小为每秒299,792,458米。
DecimalFormat 类主要靠 # 和 0 两种占位符号来指定数字长度。
- 0:表示如果位数不足则以 0 填充,
- #:表示只要有可能就把数字拉上这个位置(不包括 0)。
上面的例子包含了差不多所有的基本用法,如果你想了解更多,请参考 DecimalFormat 类的文档。
📌个别案例分析:
针对上面的使用,常用的就是保留小数点问题,对此,程序羊将DecimalFormat 抽取进行三个简单的封装,分别是默认的、正常四舍五入和只保留,不进行四舍五入的三个方法,方便下面案例进行调用演示:
package com.example.business.util;import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;/*** @ClassName: DecimalFormatUtil* @Description: 保留小数点相关类* @Author yang* @Date 2022/9/21* @Version 1.0*/
public class DecimalFormatUtil {/*** 获取Double格式化,根据format保留n个小数点(不会四舍五入)* 默认采用的舍入策略是:四舍六入五奇偶。(以保留一位小数为例)* 如 4.56 就是 4.6, 最后一位小数大于等于 6 就向前进一位.* 4.54 就是 4.5, 最后一位小数小于等于 4, 就舍去* 4.45 就是 4.4 ; 4.55 就是 4.6 最后一位小数是 5 的时候,当前一位是奇数的时候就进一位凑成偶数,当前一位是偶数的时候就舍去.* 不要四舍五入的方法就是: df.setRoundingMode(RoundingMode.DOWN);** @param strVal Double值* @param format 格式化字符串,#.##代表获取所有整数位并保留两位小数* @return*/public static String getDoubleFormat(Double strVal, String format) {if (format == null || format.isEmpty() || format.equals("null")) {format = "#.##";}DecimalFormat df = new DecimalFormat(format);df.setRoundingMode(RoundingMode.DOWN);String fm = df.format(strVal);return fm;}/*** 获取Double格式化,根据format保留n个小数点(会四舍五入)** @param strVal Double值* @param format 格式化字符串,#.##代表获取所有整数位并保留两位小数* @return*/public static String getDoubleFormatByRound(Double strVal, String format) {if (format == null || format.isEmpty() || format.equals("null")) {format = "#.##";}DecimalFormat df = new DecimalFormat(format);df.setRoundingMode(RoundingMode.HALF_UP);//HALF_UP四舍五入String fm = df.format(new BigDecimal(String.valueOf(strVal)));return fm;}/*** 获取Double格式化,根据format保留n个小数点(默认策略)** @param strVal Double值* @param format 格式化字符串,#.##代表获取所有整数位并保留两位小数* @return*/public static String getDoubleFormatByDefault(Double strVal, String format) {if (format == null || format.isEmpty() || format.equals("null")) {format = "#.##";}DecimalFormat df = new DecimalFormat(format);String fm = df.format(new BigDecimal(String.valueOf(strVal)));return fm;}}
(1)默认的:比较少用,使用的是进位方式是RoundingMode.HALF_EVEN,此舍入模式也称为“银行家算法”,主要在美国使用。
银行家算法:四舍六入五考虑,五后非零就进一,五后为零看奇偶,五前为偶应舍去,五前为奇要进一。 |
规律就是看进舍位的前一位是奇数还是偶数
- 奇数:四舍五入
- 偶数:五舍六入
- 若进舍位是5,且后面非0,进一
- 如3.25,保存一位小数,进舍位前一位是2,2是偶数,五舍六入的结果就是3.2,如果是3.26,那结果就是3.3;
- 如3.251,保存一位小数,5后面非0,所以会进一,即3.3;
- 如3.35,保存一位小数,进舍位前一位是3,3是奇数,四舍五入的结果就是3.4。
(2)如果想实现普通的四舍五入,增加下面代码,切换进位方式 df.setRoundingMode(RoundingMode.HALF_UP);
(3)如果不想实现四舍五入,增加下面代码,切换进位方式,即相当于截断 df.setRoundingMode(RoundingMode.DOWN);
format的时候注意要使用 new BigDecimal
,防止浮点型出现精度丢失的问题!
📌各种场景案例演示:
1.使用#占位符号,保留一位小数点,没有0的情况
double num = 4.56;
String doubleFormat1 = DecimalFormatUtil.getDoubleFormatByDefault(num, "#.#");
String doubleFormat2 = DecimalFormatUtil.getDoubleFormatByRound(num, "#.#");
String doubleFormat3 = DecimalFormatUtil.getDoubleFormat(num, "#.#");
System.out.println("DecimalFormat默认策略:" + doubleFormat1);
System.out.println("HALF_UP正常四舍五入:" + doubleFormat2);
System.out.println("只保留,不进行四舍五入" + doubleFormat3);
输出结果:
DecimalFormat默认策略:4.6
HALF_UP正常四舍五入:4.6
只保留,不进行四舍五入:4.5
2.使用#占位符号,保留一位小数点,有0的情况,不保留0
double num = 3.05;
String doubleFormat1 = DecimalFormatUtil.getDoubleFormatByDefault(num, "#.#");
String doubleFormat2 = DecimalFormatUtil.getDoubleFormatByRound(num, "#.#");
String doubleFormat3 = DecimalFormatUtil.getDoubleFormat(num, "#.#");
System.out.println("DecimalFormat默认策略:" + doubleFormat1);
System.out.println("HALF_UP正常四舍五入:" + doubleFormat2);
System.out.println("只保留,不进行四舍五入:" + doubleFormat3);
输出结果:
DecimalFormat默认策略:3
HALF_UP正常四舍五入:3.1
只保留,不进行四舍五入:3
PS:使用#占位符号的时候,遇到保留位数刚好有0存在的时候,则会省略,要想保留,使用0占位符号来指定,如下:
3.使用0占位符号,保留一位小数点,有0的情况,保留0
double num = 3.05;
String doubleFormat1 = DecimalFormatUtil.getDoubleFormatByDefault(num, "0.0");
String doubleFormat2 = DecimalFormatUtil.getDoubleFormatByRound(num, "0.0");
String doubleFormat3 = DecimalFormatUtil.getDoubleFormat(num, "0.0");
System.out.println("DecimalFormat默认策略:" + doubleFormat1);
System.out.println("HALF_UP正常四舍五入:" + doubleFormat2);
System.out.println("只保留,不进行四舍五入:" + doubleFormat3);
输出结果:
DecimalFormat默认策略:3.0
HALF_UP正常四舍五入:3.1
只保留,不进行四舍五入:3.0
4.使用0占位符号,保留四位小数点,且目标数的位数不够时
double num = 4.54;
String doubleFormat1 = StringVerifyUtil.getDoubleFormatByDefault(num, "0.0000");
String doubleFormat2 = StringVerifyUtil.getDoubleFormatByRound(num, "0.0000");
String doubleFormat3 = StringVerifyUtil.getDoubleFormat(num, "0.0000");
System.out.println("DecimalFormat默认策略:" + doubleFormat1);
System.out.println("HALF_UP正常四舍五入:" + doubleFormat2);
System.out.println("只保留,不进行四舍五入:" + doubleFormat3);
输出结果:
DecimalFormat默认策略:4.5400
HALF_UP正常四舍五入:4.5400
只保留,不进行四舍五入:4.5400
5.使用#占位符号,保留四位小数点,且目标数的位数不够时
double num = 4.54;
String doubleFormat1 = StringVerifyUtil.getDoubleFormatByDefault(num, "#.####");
String doubleFormat2 = StringVerifyUtil.getDoubleFormatByRound(num, "#.####");
String doubleFormat3 = StringVerifyUtil.getDoubleFormat(num, "#.####");
System.out.println("DecimalFormat默认策略:" + doubleFormat1);
System.out.println("HALF_UP正常四舍五入:" + doubleFormat2);
System.out.println("只保留,不进行四舍五入:" + doubleFormat3);
输出结果:
DecimalFormat默认策略:4.54
HALF_UP正常四舍五入:4.54
只保留,不进行四舍五入:4.54
