zoukankan      html  css  js  c++  java
  • BigDecimal四舍五入保留两位小数

    import java.math.BigDecimal;
    import java.text.DecimalFormat;
    import java.text.NumberFormat;
    public class NumberFormatDemo {
        public static void main(String[] args) {
            // BigDecimal
            // 保留两位小数
            System.out.println(new BigDecimal(0.2).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());// 0.2
            System.out.println(new BigDecimal(0.235).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());// 0.23
            System.out.println(new BigDecimal(0.2351).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());// 0.24
            System.out.println(new BigDecimal(42).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());// 42.0
    
            // NumberFormat
            // 保留两位小数,个位无数字填充0
            NumberFormat nformat = NumberFormat.getNumberInstance();
            nformat.setMaximumFractionDigits(2);
            System.out.println(nformat.format(0.2));// 0.2
            System.out.println(nformat.format(0.235));// 0.23
            System.out.println(nformat.format(0.2351));// 0.24
            System.out.println(nformat.format(42));// 42
    
            // DecimalFormat,是NumberFormat的具体实现子类
            // 保留两位小数,对应位上无数字填充0
            DecimalFormat df = new DecimalFormat("#0.00");
            System.out.println(df.format(0.2));// 0.20
            System.out.println(df.format(0.235));// 0.23
            System.out.println(df.format(0.2351));// 0.2, 因为0.2351在0.23-0.24之间,距离0.24更近,所以输出0.24
            System.out.println(df.format(42));// 42.00
    
            DecimalFormat df4 = new DecimalFormat();
            // #:位置上无数字不显示
            df4.applyPattern("#.##");
            System.out.println(df4.format(345235.0));// 345235
            // 0:位置上无数字显示0
            df4.applyPattern("0.00");
            System.out.println(df4.format(345235.0));// 345235.00
            // 加负数显示
            df4.applyPattern("-0.00");
            System.out.println(df4.format(345235.34567));// -345235.35
            // 逗号分隔
            df4.applyPattern("-0,000.00");
            System.out.println(df4.format(345235.34567));// -345,235.35
            // 百分位
            df4.applyPattern("0.00%");
            System.out.println(df4.format(0.34567));// 34.57%
            // 千分位
            df4.applyPattern("0.00u2030");
            System.out.println(df4.format(0.34567));// 345.67‰
            // 科学计数法,E之前是底数的格式,E之后的是指数的格式
            df4.applyPattern("0.00E00");
            System.out.println(df4.format(2342.444));// 2.34E03
            // 格式后面加单位符号
            df4.applyPattern("0.00 KG");
            System.out.println(df4.format(2342.444));// 2342.44 KG
            df4.applyPattern("0.00 QA");
            System.out.println(df4.format(2342.444));// 2342.44 QA
            // 使用舍入模式:ROUND_HALF_EVEN,
            // 保留位数是奇数,使用ROUND_HALF_DOWN
            // 保留位数是偶数,使用ROUND_HALF_UP
            System.out.println(df4.format(2342.435));// 2342.43 QA
            System.out.println(df4.format(2342.445));// 2342.45 QA
    
            // String.format
            // 保留两位小数,个位数及小数点后两位无数字填充0,四舍五入
            System.out.println(String.format("%.2f", 0.2));// 0.20
            System.out.println(String.format("%.2f", 0.235));// 0.24
            System.out.println(String.format("%.2f", 0.236));// 0.24
            System.out.println(String.format("%.2f", 42.0));// 42.00
        }
    }

    BigDecimal工具类
    总所周知,java在浮点型运算时是非精确计算,如下demo

    System.out.println(0.05 + 0.01);// 0.060000000000000005
    System.out.println(1.0 - 0.42);// 0.5800000000000001
    System.out.println(4.015 * 100);// 401.49999999999994
    System.out.println(123.3 / 100);// 1.2329999999999999
    1
    2
    3
    4
    在商业运算中,这点微小的误差有可能造成非常严重的后果。
    所以在商业应用开发中,涉及金额等浮点数计算的数据,全部使用BigDecimal进行加减乘除计算

    BigDecimal工具类代码:
    import java.math.BigDecimal;
    public class BigDecimalUtil {
    // 默认除法运算精度
    private static final int DEFAULT_DIV_SCALE = 5;

    /**
    * 提供精确的加法运算
    *
    * @param v1
    * @param v2
    * @return
    */
    public static double add(double v1, double v2) {
    BigDecimal b1 = new BigDecimal(v1);
    BigDecimal b2 = new BigDecimal(v2);
    return b1.add(b2).doubleValue();
    }

    public static String add(String v1, String v2) {
    BigDecimal b1 = new BigDecimal(v1);
    BigDecimal b2 = new BigDecimal(v2);
    return b1.add(b2).toString();
    }

    /**
    * 提供精确的减法运算
    *
    * @param v1
    * @param v2
    * @return
    */
    public static double subtract(double v1, double v2) {
    BigDecimal b1 = new BigDecimal(v1);
    BigDecimal b2 = new BigDecimal(v2);
    return b1.subtract(b2).doubleValue();
    }

    public static String substract(String v1, String v2) {
    BigDecimal b1 = new BigDecimal(v1);
    BigDecimal b2 = new BigDecimal(v2);
    return b1.subtract(b2).toString();
    }

    /**
    * 提供精确的乘法运算
    *
    * @param v1
    * @param v2
    * @return
    */
    public static double multiply(double v1, double v2) {
    BigDecimal b1 = new BigDecimal(v1);
    BigDecimal b2 = new BigDecimal(v2);
    return b1.multiply(b2).doubleValue();
    }

    public static String multiply(String v1, String v2) {
    BigDecimal b1 = new BigDecimal(v1);
    BigDecimal b2 = new BigDecimal(v2);
    return b1.multiply(b2).toString();
    }

    /**
    * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入,舍入模式采用ROUND_HALF_UP
    *
    * @param v1
    * @param v2
    * @return 两个参数的商
    */
    public static double divide(double v1, double v2) {
    return divide(v1, v2, DEFAULT_DIV_SCALE);
    }

    /**
    * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。舍入模式采用ROUND_HALF_UP
    *
    * @param v1
    * @param v2
    * @param scale
    * 表示需要精确到小数点以后几位。
    * @return 两个参数的商
    */
    public static double divide(double v1, double v2, int scale) {
    return divide(v1, v2, scale, BigDecimal.ROUND_HALF_UP);
    }

    /**
    * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。舍入模式采用用户指定舍入模式
    *
    * @param v1
    * @param v2
    * @param scale
    * 表示需要精确到小数点以后几位
    * @param round_mode
    * 表示用户指定的舍入模式
    * @return 两个参数的商
    */
    public static double divide(double v1, double v2, int scale, int round_mode) {
    if (scale < 0) {
    throw new IllegalArgumentException("The scale must be a positive integer or zero");
    }
    BigDecimal b1 = new BigDecimal(Double.toString(v1));
    BigDecimal b2 = new BigDecimal(Double.toString(v2));
    return b1.divide(b2, scale, round_mode).doubleValue();
    }

    /**
    * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入,舍入模式采用ROUND_HALF_EVEN
    *
    * @param v1
    * @param v2
    * @return 两个参数的商,以字符串格式返回
    */
    public static String divide(String v1, String v2) {
    return divide(v1, v2, DEFAULT_DIV_SCALE);
    }

    /**
    * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。舍入模式采用ROUND_HALF_UP
    *
    * @param v1
    * @param v2
    * @param scale
    * 表示需要精确到小数点以后几位
    * @return 两个参数的商,以字符串格式返回
    */
    public static String divide(String v1, String v2, int scale) {
    return divide(v1, v2, scale, BigDecimal.ROUND_HALF_UP);
    }

    /**
    * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。舍入模式采用用户指定舍入模式
    *
    * @param v1
    * @param v2
    * @param scale
    * 表示需要精确到小数点以后几位
    * @param round_mode
    * 表示用户指定的舍入模式
    * @return 两个参数的商,以字符串格式返回
    */
    public static String divide(String v1, String v2, int scale, int round_mode) {
    if (scale < 0) {
    throw new IllegalArgumentException("The scale must be a positive integer or zero");
    }
    BigDecimal b1 = new BigDecimal(v1);
    BigDecimal b2 = new BigDecimal(v2);
    return b1.divide(b2, scale, round_mode).toString();
    }

    /**
    * 提供精确的小数位四舍五入处理,舍入模式采用ROUND_HALF_EVEN
    *
    * @param v
    * 需要四舍五入的数字
    * @param scale
    * 小数点后保留几位
    * @return 四舍五入后的结果
    */
    public static double round(double v, int scale) {
    return round(v, scale, BigDecimal.ROUND_HALF_UP);
    }

    /**
    * 提供精确的小数位四舍五入处理
    *
    * @param v
    * 需要四舍五入的数字
    * @param scale
    * 小数点后保留几位
    * @param round_mode
    * 指定的舍入模式
    * @return 四舍五入后的结果
    */
    public static double round(double v, int scale, int round_mode) {
    if (scale < 0) {
    throw new IllegalArgumentException("The scale must be a positive integer or zero");
    }
    BigDecimal b = new BigDecimal(Double.toString(v));
    return b.setScale(scale, round_mode).doubleValue();
    }

    /**
    * 提供精确的小数位四舍五入处理,舍入模式采用ROUND_HALF_UP
    *
    * @param v
    * 需要四舍五入的数字
    * @param scale
    * 小数点后保留几位
    * @return 四舍五入后的结果,以字符串格式返回
    */
    public static String round(String v, int scale) {
    return round(v, scale, BigDecimal.ROUND_HALF_UP);
    }

    /**
    * 提供精确的小数位四舍五入处理
    *
    * @param v
    * 需要四舍五入的数字
    * @param scale
    * 小数点后保留几位
    * @param round_mode
    * 指定的舍入模式
    * @return 四舍五入后的结果,以字符串格式返回
    */
    public static String round(String v, int scale, int round_mode) {
    if (scale < 0) {
    throw new IllegalArgumentException("The scale must be a positive integer or zero");
    }
    BigDecimal b = new BigDecimal(v);
    return b.setScale(scale, round_mode).toString();
    }
    }

    BigDecimal 舍入模式(Rounding mode)介绍:
    ROUND_CEILING
    向正无穷方向舍入
    ROUND_DOWN
    向零方向舍入
    ROUND_FLOOR
    向负无穷方向舍入
    ROUND_HALF_DOWN
    向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向下舍入, 例如1.55 保留一位小数结果为1.5
    ROUND_HALF_EVEN
    向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,如果保留位数是奇数,使用: : ROUND_HALF_DOWN如果是偶数,使用ROUND_HALF_UP
    ROUND_HALF_UP
    向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向上舍入, 1.55保留一位小数结果为1.6
    ROUND_UNNECESSARY
    计算结果是精确的,不需要舍入模式
    ROUND_UP
    向远离0的方向舍入

    https://blog.csdn.net/mglgcx/article/details/78560029?locationNum=10&fps=1

    http://www.hollischuang.com/archives/618

  • 相关阅读:
    golang/windows如何删除只读属性文件
    golang/TLS 采坑
    gsweb —— 理解HTTP协议
    gsweb —— 自己动手用golang写WEB框架
    Scala冒泡排序、快排、归并
    Hadoop自动化部署脚本
    大数据学习笔记
    vim键盘图
    什么是回调或高级函数?
    使用CSS表达式去除超链接的虚框的一些方法
  • 原文地址:https://www.cnblogs.com/shy1766IT/p/10262325.html
Copyright © 2011-2022 走看看