基於BigDecimal的精確計算以及格式化輸出代碼示例

package common;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;


/**
 * batch-parent.common <br/>
 * Created by PengRong on 2017/12/22. <br/>
 *
 * @author PengRong <br/>
 * @Description ExactCompute ,java 原生的float ,double 只是適合用於科學計算,工程計算。不適合商業計算。
 * 商業計算一般使用BigDecimanl 類進行 精確 計算
 * @ClassName: ${ExactCompute}
 * @since 2017-12-22 16:43 <br/>
 */
public class ExactCompute {
        /**
         *   ROUND_CEILING
         如果   BigDecimal   是正的,則做   ROUND_UP   操作;如果爲負,則做   ROUND_DOWN   操作。
         ROUND_DOWN
         從不在捨棄(即截斷)的小數之前增加數字。
         ROUND_FLOOR
         如果   BigDecimal   爲正,則作   ROUND_UP   ;如果爲負,則作   ROUND_DOWN   。
         ROUND_HALF_DOWN
         若捨棄部分>   .5,則作   ROUND_UP;否則,作   ROUND_DOWN   。
         ROUND_HALF_EVEN
         如果捨棄部分左邊的數字爲奇數,則作   ROUND_HALF_UP   ;如果它爲偶數,則作爲ROUND_HALF_DOWN
         ROUND_HALF_UP
         若捨棄部分>=.5,則作   ROUND_UP   ;否則,作   ROUND_DOWN
         ROUND_UNNECESSARY
         該“僞舍入模式”實際是指明所要求的操作必須是精確的,,因此不需要舍入操作。
         ROUND_UP
         總是在非   0   捨棄小數(即截斷)之前增加數字。
         */
        /**
         * double 精確相加
         *
         * @param parama
         * @param paramb
         * @return
         */
        public static BigDecimal add(double parama, double paramb) {
                BigDecimal bigDecimala = new BigDecimal(Double.toString(parama));
                BigDecimal bigDecimalb = new BigDecimal(Double.toString(paramb));
                return bigDecimala.add(bigDecimalb);
        }

        /**
         * double 精確相減
         *
         * @param parama
         * @param paramb
         * @return
         */
        public static BigDecimal sub(double parama, double paramb) {
                BigDecimal bigDecimala = new BigDecimal(Double.toString(parama));
                BigDecimal bigDecimalb = new BigDecimal(Double.toString(paramb));
                return bigDecimala.subtract(bigDecimalb);
        }

        /**
         * double 精確相乘
         * @param parama
         * @param paramb
         * @return
         */
        public static BigDecimal mul(double parama, double paramb) {
                BigDecimal bigDecimala = new BigDecimal(Double.toString(parama));
                BigDecimal bigDecimalb = new BigDecimal(Double.toString(paramb));
                return bigDecimala.multiply(bigDecimalb);
        }

        /**
         * 計算: value1/value2 </br>
         * @param value1      被除數 </br>
         * @param value2      除數 </br>
         * @param scale       精度 定義了返回值的精度,表示精確到小數點後面幾位
         *                    (又叫標度,就是科學計數法的指數 <tt>(10<sup>scale</sup> &times; val)</tt>)</br>
         * @param routingMode 定義返回值的四捨五入模式 ;默認使用: BigDecimal.ROUND_HALF_UP 模式</br>
         * @return
         * @throws IllegalAccessException
         */
        public static BigDecimal div(double value1, double value2, int scale, int routingMode) throws IllegalAccessException {
                //如果精確範圍小於0,拋出異常信息
                if (scale < 0) {
                        throw new IllegalAccessException("精確度不能小於0");
                }
                if (routingMode <= 0) {
                        routingMode = BigDecimal.ROUND_HALF_UP;
                }
                BigDecimal b1 = new BigDecimal(Double.toString(value1));
                BigDecimal b2 = new BigDecimal(Double.toString(value2));
                BigDecimal result = b1.divide(b2, scale, routingMode);
                // System.out.println(result.toBigInteger());
                // System.out.println(result.toString());
                return result;
        }

        /**
         * 對value參數提供精確的小數位四捨五入處理。
         *
         * @param value 需要四捨五入的數字</br>
         * @param scale 期望小數點後保留幾位 </br>
         * @return
         */
        public static double round(double value, int scale) {
                double result = 0.00;
                if (scale < 0) {
                        throw new IllegalArgumentException("The scale must be a positive integer or zero");
                }
                BigDecimal valueBig = new BigDecimal(Double.toString(value));
                BigDecimal one = new BigDecimal(Double.toString(1));
                result = valueBig.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
                return result;
        }

        /**
         * 格式化 BigDecimal 爲一個字符串序列;兩個小數位,小數第二位 進行 四捨五入。
         *
         * @param bigDecimal
         * @return
         */
        public static String formatBigDecimal(BigDecimal bigDecimal) {
                DecimalFormat format = (DecimalFormat) DecimalFormat.getInstance(Locale.CHINA);
                format.setDecimalSeparatorAlwaysShown(true);
                /** 設置小數部分允許的最大位數  */
                format.setMaximumFractionDigits(3);
                /** 設置小數部分允許的最小位數  */
                format.setMinimumFractionDigits(0);
                format.applyPattern(",###.00");
                return format.format(bigDecimal);

        }

        public static void main(String[] args) throws IllegalAccessException {
                System.out.println(String.valueOf(1212.4545523542));
                System.out.println(add(121.454, 545.15454));
                //格式化精確計算後的值
                System.out.println("formatBigDecimal: "+formatBigDecimal(add(12455451.454, 545.15454)));
                System.out.println(sub(121.454, 545.15454));
                System.out.println(mul(121.454, 545.15454));
                System.out.println(div(1, 3, 5, BigDecimal.ROUND_HALF_UP));
                System.out.println(round(12154.4565, 2));
                System.out.println(add(121.454, 545.15454));
                System.out.println(sub(121.454, 545.15454));
                System.out.println(mul(121.454, 545.15454));
                System.out.println(div(1, 3, 5, BigDecimal.ROUND_HALF_UP));

                /**
                 * NumberFormat 數字形式的格式化
                 */
                NumberFormat nFormat=NumberFormat.getNumberInstance();
                nFormat.setMinimumIntegerDigits(3);//設置整數部分至少爲3位
                nFormat.setMaximumFractionDigits(5);//設置小數點位數爲5
                System.out.println("Format Out 3.2128345= "+nFormat.format(3.2128345));
                // 貨幣形式格式化
                NumberFormat cFormat=NumberFormat.getCurrencyInstance();
                cFormat.setMaximumFractionDigits(3);
                System.out.println("Format Out 321283.47656="+cFormat.format(321283.47656));
                // 百分比形式
                NumberFormat percentFormat=NumberFormat.getPercentInstance();
                percentFormat.setMaximumFractionDigits(4);
                System.out.println("Format Out 3.2128345="+percentFormat.format(3.2128345));
                System.out.println("Format Out 3.2128345="+percentFormat.format(0.2128345));

                //System.out.println("Format Out null="+nFormat.format(null));//參數是null,出現異常
        }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章