成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java中的BigDecimal,你真的會用嗎?

開發 后端
雙精度浮點型變量double可以處理16位有效數,但在實際應用中,可能需要對更大或者更小的數進行運算和處理。

一、BigDecimal概述

Java在java.math包中提供的API類BigDecimal,用來對超過16位有效位的數進行精確的運算。雙精度浮點型變量double可以處理16位有效數,但在實際應用中,可能需要對更大或者更小的數進行運算和處理。

一般情況下,對于那些不需要準確計算精度的數字,我們可以直接使用Float和Double處理,但是Double.valueOf(String) 和Float.valueOf(String)會丟失精度。所以開發中,如果我們需要精確計算的結果,則必須使用BigDecimal類來操作。

BigDecimal所創建的是對象,故我們不能使用傳統的+、-、*、/等算術運算符直接對其對象進行數學運算,而必須調用其相對應的方法。方法中的參數也必須是BigDecimal的對象。構造器是類的特殊方法,專門用來創建對象,特別是帶有參數的對象。

二、BigDecimal常用構造函數

2.1、常用構造函數

  •  BigDecimal(int)

創建一個具有參數所指定整數值的對象

  •  BigDecimal(double)

創建一個具有參數所指定雙精度值的對象

  •  BigDecimal(long)

創建一個具有參數所指定長整數值的對象

  •     BigDecimal(String)

創建一個具有參數所指定以字符串表示的數值的對象

2.2、使用問題分析

使用示例: 

  1. BigDecimal a =new BigDecimal(0.1);  
  2. System.out.println("a values is:"+a);  
  3. System.out.println("=====================");  
  4. BigDecimal b =new BigDecimal("0.1");  
  5. System.out.println("b values is:"+b); 

結果示例: 

  1. a values is:0.1000000000000000055511151231257827021181583404541015625  
  2. =====================  
  3. b values is:0.1 

原因分析:

1)參數類型為double的構造方法的結果有一定的不可預知性。有人可能認為在Java中寫入newBigDecimal(0.1)所創建的BigDecimal正好等于 0.1(非標度值 1,其標度為 1),但是它實際上等于0.1000000000000000055511151231257827021181583404541015625。這是因為0.1無法準確地表示為 double(或者說對于該情況,不能表示為任何有限長度的二進制小數)。這樣,傳入到構造方法的值不會正好等于 0.1(雖然表面上等于該值)。

2)String 構造方法是完全可預知的:寫入 newBigDecimal(“0.1”) 將創建一個 BigDecimal,它正好等于預期的 0.1。因此,比較而言, 通常建議優先使用String構造方法。

3)當double必須用作BigDecimal的源時,請注意,此構造方法提供了一個準確轉換;它不提供與以下操作相同的結果:先使用Double.toString(double)方法,然后使用BigDecimal(String)構造方法,將double轉換為String。要獲取該結果,請使用static valueOf(double)方法。Java知音公眾號內回復“面試題聚合”,送你一份面試題寶典

三、BigDecimal常用方法詳解

3.1、常用方法

  •  add(BigDecimal)

BigDecimal對象中的值相加,返回BigDecimal對象

  •  subtract(BigDecimal)

BigDecimal對象中的值相減,返回BigDecimal對象

  •  multiply(BigDecimal)

BigDecimal對象中的值相乘,返回BigDecimal對象

  •  divide(BigDecimal)

BigDecimal對象中的值相除,返回BigDecimal對象

  •  toString()

將BigDecimal對象中的值轉換成字符串

  •  doubleValue()

將BigDecimal對象中的值轉換成雙精度數

  •  floatValue()

將BigDecimal對象中的值轉換成單精度數

  •  longValue()

將BigDecimal對象中的值轉換成長整數

  •  intValue()

將BigDecimal對象中的值轉換成整數

3.2、BigDecimal大小比較

java中對BigDecimal比較大小一般用的是bigdemical的compareTo方法 

  1. int a = bigdemical.compareTo(bigdemical2) 

返回結果分析: 

  1. a = -1,表示bigdemical小于bigdemical2;  
  2. a = 0,表示bigdemical等于bigdemical2;  
  3. a = 1,表示bigdemical大于bigdemical2; 

舉例:a大于等于b 

  1. new bigdemica(a).compareTo(new bigdemical(b)) >= 0 

四、BigDecimal格式化

由于NumberFormat類的format()方法可以使用BigDecimal對象作為其參數,可以利用BigDecimal對超出16位有效數字的貨幣值,百分值,以及一般數值進行格式化控制。

以利用BigDecimal對貨幣和百分比格式化為例。首先,創建BigDecimal對象,進行BigDecimal的算術運算后,分別建立對貨幣和百分比格式化的引用,最后利用BigDecimal對象作為format()方法的參數,輸出其格式化的貨幣值和百分比。 

  1. NumberFormat currency = NumberFormat.getCurrencyInstance(); //建立貨幣格式化引用   
  2. NumberFormat percent = NumberFormat.getPercentInstance();  //建立百分比格式化引用   
  3. percent.setMaximumFractionDigits(3); //百分比小數點最多3位   
  4. BigDecimal loanAmount = new BigDecimal("15000.48"); //貸款金額  
  5. BigDecimal interestRate = new BigDecimal("0.008"); //利率     
  6. BigDecimal interest = loanAmount.multiply(interestRate); //相乘  
  7. System.out.println("貸款金額:\t" + currency.format(loanAmount));   
  8. System.out.println("利率:\t" + percent.format(interestRate));   
  9. System.out.println("利息:\t" + currency.format(interest));  

結果:

  1. 貸款金額: ¥15,000.48 利率: 0.8% 利息: ¥120.00 

BigDecimal格式化保留2為小數,不足則補0: 

  1. public class NumberFormat {  
  2.     public static void main(String[] s){  
  3.         System.out.println(formatToNumber(new BigDecimal("3.435")));  
  4.         System.out.println(formatToNumber(new BigDecimal(0)));  
  5.         System.out.println(formatToNumber(new BigDecimal("0.00")));  
  6.         System.out.println(formatToNumber(new BigDecimal("0.001")));  
  7.         System.out.println(formatToNumber(new BigDecimal("0.006")));  
  8.         System.out.println(formatToNumber(new BigDecimal("0.206")));  
  9.     }  
  10.     /**  
  11.      * @desc 1.0~1之間的BigDecimal小數,格式化后失去前面的0,則前面直接加上0。  
  12.      * 2.傳入的參數等于0,則直接返回字符串"0.00"  
  13.      * 3.大于1的小數,直接格式化返回字符串  
  14.      * @param obj傳入的小數  
  15.      * @return  
  16.      */  
  17.     public static String formatToNumber(BigDecimal obj) {  
  18.         DecimalFormat df = new DecimalFormat("#.00");  
  19.         if(obj.compareTo(BigDecimal.ZERO)==0) {  
  20.             return "0.00";  
  21.         }else if(obj.compareTo(BigDecimal.ZERO)>0&&obj.compareTo(new BigDecimal(1))<0){  
  22.             return "0"+df.format(obj).toString();  
  23.         }else {  
  24.             return df.format(obj).toString();  
  25.         }  
  26.     }  

結果為: 

  1. 3.44  
  2. 0.00  
  3. 0.00  
  4. 0.00  
  5. 0.01  
  6. 0.21 

五、BigDecimal常見異常

5.1、除法的時候出現異常

java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result

原因分析:

通過BigDecimal的divide方法進行除法時當不整除,出現無限循環小數時,就會拋異常:java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

解決方法:

 divide方法設置精確的小數點,如:divide(xxxxx,2)

六、BigDecimal總結

6.1、總結

在需要精確的小數計算時再使用BigDecimal,BigDecimal的性能比double和float差,在處理龐大,復雜的運算時尤為明顯。故一般精度的計算沒必要使用BigDecimal。

盡量使用參數類型為String的構造函數。

BigDecimal都是不可變的(immutable)的, 在進行每一次四則運算時,都會產生一個新的對象 ,所以在做加減乘除運算時要記得要保存操作后的值。

6.2、工具類推薦 

  1. package com.vivo.ars.util;  
  2. import java.math.BigDecimal;  
  3. /**  
  4.  * 用于高精確處理常用的數學運算  
  5.  */  
  6. public class ArithmeticUtils {  
  7.     //默認除法運算精度  
  8.     private static final int DEF_DIV_SCALE = 10 
  9.     /**  
  10.      * 提供精確的加法運算  
  11.      *  
  12.      * @param v1 被加數  
  13.      * @param v2 加數  
  14.      * @return 兩個參數的和  
  15.      */  
  16.     public static double add(double v1, double v2) {  
  17.         BigDecimal b1 = new BigDecimal(Double.toString(v1));  
  18.         BigDecimal b2 = new BigDecimal(Double.toString(v2));  
  19.         return b1.add(b2).doubleValue();  
  20.     }  
  21.     /**  
  22.      * 提供精確的加法運算  
  23.      *  
  24.      * @param v1 被加數  
  25.      * @param v2 加數  
  26.      * @return 兩個參數的和  
  27.      */  
  28.     public static BigDecimal add(String v1, String v2) {  
  29.         BigDecimal b1 = new BigDecimal(v1);  
  30.         BigDecimal b2 = new BigDecimal(v2);  
  31.         return b1.add(b2); 
  32.      } 
  33.     /**  
  34.      * 提供精確的加法運算  
  35.      *  
  36.      * @param v1    被加數  
  37.      * @param v2    加數  
  38.      * @param scale 保留scale 位小數  
  39.      * @return 兩個參數的和  
  40.      */  
  41.     public static String add(String v1, String v2, int scale) {  
  42.         if (scale < 0) {  
  43.             throw new IllegalArgumentException(  
  44.                     "The scale must be a positive integer or zero");  
  45.         }  
  46.         BigDecimal b1 = new BigDecimal(v1);  
  47.         BigDecimal b2 = new BigDecimal(v2);  
  48.         return b1.add(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();  
  49.     }  
  50.     /**  
  51.      * 提供精確的減法運算  
  52.      *  
  53.      * @param v1 被減數  
  54.      * @param v2 減數  
  55.      * @return 兩個參數的差  
  56.      */ 
  57.      public static double sub(double v1, double v2) {  
  58.         BigDecimal b1 = new BigDecimal(Double.toString(v1));  
  59.         BigDecimal b2 = new BigDecimal(Double.toString(v2));  
  60.         return b1.subtract(b2).doubleValue();  
  61.     }  
  62.     /**  
  63.      * 提供精確的減法運算。  
  64.      *  
  65.      * @param v1 被減數  
  66.      * @param v2 減數  
  67.      * @return 兩個參數的差  
  68.      */  
  69.     public static BigDecimal sub(String v1, String v2) {  
  70.         BigDecimal b1 = new BigDecimal(v1);  
  71.         BigDecimal b2 = new BigDecimal(v2); 
  72.          return b1.subtract(b2);  
  73.     }  
  74.     /**  
  75.      * 提供精確的減法運算  
  76.      * 
  77.      * @param v1    被減數  
  78.      * @param v2    減數  
  79.      * @param scale 保留scale 位小數  
  80.      * @return 兩個參數的差  
  81.      */  
  82.     public static String sub(String v1, String v2, int scale) {  
  83.         if (scale < 0) {  
  84.             throw new IllegalArgumentException(  
  85.                     "The scale must be a positive integer or zero");  
  86.         }  
  87.         BigDecimal b1 = new BigDecimal(v1);  
  88.         BigDecimal b2 = new BigDecimal(v2);  
  89.         return b1.subtract(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();  
  90.     }  
  91.     /**  
  92.      * 提供精確的乘法運算  
  93.      *  
  94.      * @param v1 被乘數  
  95.      * @param v2 乘數  
  96.      * @return 兩個參數的積  
  97.      */  
  98.     public static double mul(double v1, double v2) {  
  99.         BigDecimal b1 = new BigDecimal(Double.toString(v1));  
  100.         BigDecimal b2 = new BigDecimal(Double.toString(v2));  
  101.         return b1.multiply(b2).doubleValue();  
  102.     }  
  103.     /**  
  104.      * 提供精確的乘法運算  
  105.      *  
  106.      * @param v1 被乘數  
  107.      * @param v2 乘數  
  108.      * @return 兩個參數的積  
  109.      */  
  110.     public static BigDecimal mul(String v1, String v2) {  
  111.         BigDecimal b1 = new BigDecimal(v1);  
  112.         BigDecimal b2 = new BigDecimal(v2);  
  113.         return b1.multiply(b2);  
  114.     }  
  115.     /**  
  116.      * 提供精確的乘法運算  
  117.      *  
  118.      * @param v1    被乘數  
  119.      * @param v2    乘數  
  120.      * @param scale 保留scale 位小數  
  121.      * @return 兩個參數的積  
  122.      */  
  123.     public static double mul(double v1, double v2, int scale) {  
  124.         BigDecimal b1 = new BigDecimal(Double.toString(v1));  
  125.         BigDecimal b2 = new BigDecimal(Double.toString(v2));  
  126.         return round(b1.multiply(b2).doubleValue(), scale);  
  127.     }  
  128.     /**  
  129.      * 提供精確的乘法運算  
  130.      *  
  131.      * @param v1    被乘數  
  132.      * @param v2    乘數  
  133.      * @param scale 保留scale 位小數  
  134.      * @return 兩個參數的積  
  135.      */  
  136.     public static String mul(String v1, String v2, int scale) {  
  137.         if (scale < 0) {  
  138.             throw new IllegalArgumentException(  
  139.                     "The scale must be a positive integer or zero");  
  140.         }  
  141.         BigDecimal b1 = new BigDecimal(v1);  
  142.         BigDecimal b2 = new BigDecimal(v2);  
  143.         return b1.multiply(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();  
  144.     }  
  145.     /**  
  146.      * 提供(相對)精確的除法運算,當發生除不盡的情況時,精確到  
  147.      * 小數點以后10位,以后的數字四舍五入 
  148.      *  
  149.      * @param v1 被除數  
  150.      * @param v2 除數  
  151.      * @return 兩個參數的商  
  152.      */ 
  153.     public static double div(double v1, double v2) {  
  154.         return div(v1, v2, DEF_DIV_SCALE);  
  155.     }  
  156.     /**  
  157.      * 提供(相對)精確的除法運算。當發生除不盡的情況時,由scale參數指  
  158.      * 定精度,以后的數字四舍五入 
  159.      *  
  160.      * @param v1    被除數  
  161.      * @param v2    除數  
  162.      * @param scale 表示表示需要精確到小數點以后幾位。  
  163.      * @return 兩個參數的商  
  164.      */  
  165.     public static double div(double v1, double v2, int scale) {  
  166.         if (scale < 0) {  
  167.             throw new IllegalArgumentException("The scale must be a positive integer or zero");  
  168.         }  
  169.         BigDecimal b1 = new BigDecimal(Double.toString(v1));  
  170.         BigDecimal b2 = new BigDecimal(Double.toString(v2));  
  171.         return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();  
  172.     }  
  173.     /**  
  174.      * 提供(相對)精確的除法運算。當發生除不盡的情況時,由scale參數指  
  175.      * 定精度,以后的數字四舍五入  
  176.      *  
  177.      * @param v1    被除數  
  178.      * @param v2    除數  
  179.      * @param scale 表示需要精確到小數點以后幾位  
  180.      * @return 兩個參數的商  
  181.      */  
  182.     public static String div(String v1, String v2, int scale) {  
  183.         if (scale < 0) {  
  184.             throw new IllegalArgumentException("The scale must be a positive integer or zero");  
  185.         }  
  186.         BigDecimal b1 = new BigDecimal(v1); 
  187.         BigDecimal b2 = new BigDecimal(v1);  
  188.         return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).toString();  
  189.     }  
  190.     /**  
  191.      * 提供精確的小數位四舍五入處理  
  192.      *  
  193.      * @param v     需要四舍五入的數字  
  194.      * @param scale 小數點后保留幾位  
  195.      * @return 四舍五入后的結果  
  196.      */  
  197.     public static double round(double v, int scale) {  
  198.         if (scale < 0) {  
  199.             throw new IllegalArgumentException("The scale must be a positive integer or zero");  
  200.         }  
  201.         BigDecimal b = new BigDecimal(Double.toString(v));  
  202.         return b.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();  
  203.     }  
  204.     /**  
  205.      * 提供精確的小數位四舍五入處理  
  206.      *  
  207.      * @param v     需要四舍五入的數字  
  208.      * @param scale 小數點后保留幾位  
  209.      * @return 四舍五入后的結果  
  210.      */  
  211.     public static String round(String v, int scale) {  
  212.         if (scale < 0) {  
  213.             throw new IllegalArgumentException(  
  214.                     "The scale must be a positive integer or zero");  
  215.         }  
  216.         BigDecimal b = new BigDecimal(v);  
  217.         return b.setScale(scale, BigDecimal.ROUND_HALF_UP).toString();  
  218.     }  
  219.     /**  
  220.      * 取余數  
  221.      *  
  222.      * @param v1    被除數  
  223.      * @param v2    除數  
  224.      * @param scale 小數點后保留幾位  
  225.      * @return 余數  
  226.      */  
  227.     public static String remainder(String v1, String v2, int scale) {  
  228.         if (scale < 0) {  
  229.             throw new IllegalArgumentException(  
  230.                     "The scale must be a positive integer or zero");  
  231.         }  
  232.         BigDecimal b1 = new BigDecimal(v1);  
  233.         BigDecimal b2 = new BigDecimal(v2);  
  234.         return b1.remainder(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();  
  235.     }  
  236.     /**  
  237.      * 取余數  BigDecimal  
  238.      *  
  239.      * @param v1    被除數  
  240.      * @param v2    除數  
  241.      * @param scale 小數點后保留幾位  
  242.      * @return 余數  
  243.      */  
  244.     public static BigDecimal remainder(BigDecimal v1, BigDecimal v2, int scale) {  
  245.         if (scale < 0) {  
  246.             throw new IllegalArgumentException(  
  247.                     "The scale must be a positive integer or zero");  
  248.         }  
  249.         return v1.remainder(v2).setScale(scale, BigDecimal.ROUND_HALF_UP);  
  250.     }  
  251.     /**  
  252.      * 比較大小  
  253.      *  
  254.      * @param v1 被比較數  
  255.      * @param v2 比較數  
  256.      * @return 如果v1 大于v2 則 返回true 否則false  
  257.      */  
  258.     public static boolean compare(String v1, String v2) {  
  259.         BigDecimal b1 = new BigDecimal(v1);  
  260.         BigDecimal b2 = new BigDecimal(v2);  
  261.         int bj = b1.compareTo(b2);  
  262.         boolean res;  
  263.         if (bj > 0)  
  264.             res = true 
  265.         else  
  266.             res = false 
  267.         return res;  
  268.     }  
  269.  

 

責任編輯:龐桂玉 來源: Java知音
相關推薦

2018-09-29 15:34:34

JavaList接口

2023-12-01 11:13:50

JavaTreeSet

2023-06-30 08:10:14

JavaBigDecimal

2016-05-04 10:36:42

iossdwebimage開發

2025-01-20 00:00:00

反射Java語言

2022-09-22 14:55:31

前端JavaScripthis

2022-09-26 13:10:17

JavaScriptthis

2025-04-01 08:00:00

curl開發運維

2018-12-21 11:24:55

Java時間處理編程語言

2021-11-26 08:07:16

MySQL SQL 語句數據庫

2020-12-18 08:59:51

蘋果iCloud儲存照片

2024-12-27 09:29:09

2025-02-14 08:30:49

SpringJava開發

2020-03-02 14:55:02

JavaBigDecimalAPI

2023-11-01 13:48:00

反射java

2019-07-25 12:46:32

Java高并發編程語言

2021-09-08 07:49:35

Dubbo連接控制

2023-04-28 07:49:13

Javawaitsleep

2018-04-27 15:30:53

Java三目運算符

2024-03-06 08:15:03

@Autowired注入方式Spring
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 福利一区在线观看 | av国产精品 | 久久国产精品一区二区 | 天天草天天射 | 精品国产欧美 | 国产日韩亚洲欧美 | 国产一区 | 久久久久久一区 | 狠狠干av| 欧美一级片在线观看 | 欧美久久免费观看 | 成人久久久 | 成人在线一区二区三区 | 精品亚洲一区二区 | 一级做a爰片性色毛片16美国 | 国产高清视频在线播放 | 欧美一二区 | 国产高清视频一区 | 欧美精品成人一区二区三区四区 | 黄色激情毛片 | 中文字幕中文字幕 | 天天爽夜夜爽精品视频婷婷 | 日韩精品一区在线 | 日本网站免费在线观看 | 亚洲在线一区二区 | www视频在线观看 | 成人夜晚看av | 日韩精品一区二区三区免费视频 | 视频在线一区二区 | 中文字幕视频在线观看免费 | 九九成人 | 欧美性猛交一区二区三区精品 | 国产在线视频一区二区董小宛性色 | 久久精品国产亚洲a | 中文字幕91 | 波多野结衣一区二区三区在线观看 | 久久里面有精品 | 国外成人在线视频 | 免费日本视频 | 99re超碰| 欧美一级一 |