1 package com.lv.study.am.first; 2 3 import java.math.BigDecimal; 4 5 public class TestBigDecimal { 6 7 public static void main(String[] args) { 8 9 // double d1=1.0; 10 // double d2=0.9; 11 12 // System.out.println(d1-d2);//0.1 13 14 // 計算機語言-》 二進制 01 15 16 // 計算10/3 17 18 // 漏洞 吧小數點后小於2角的全部打到自己的賬號里面 19 20 // test1(); 21 // test3(); 22 test4(); 23 24 } 25 26 // 減法 27 public static void test4() { 28 BigDecimal bd1 = new BigDecimal(1.0);// 這個類沒有無參的構造器 29 BigDecimal bd2 = new BigDecimal(0.9999); 30 31 BigDecimal result = bd1.subtract(bd2);// 32 33 System.out.println(result.floatValue());// 得到浮點類型 34 System.out.println(result.intValue());//得到int類型 35 System.out.println(result.longValue()); 36 37 System.out.println(result.setScale(10,BigDecimal.ROUND_HALF_UP)); 38 39 System.out.printf("%"); 40 } 41 42 // 乘法 43 public static void test3() { 44 BigDecimal bd1 = new BigDecimal(1.0);// 這個類沒有無參的構造器 45 BigDecimal bd2 = new BigDecimal(0.9); 46 47 BigDecimal result = bd1.multiply(bd2);// 48 49 System.out.println(result.floatValue());// 得到浮點類型 50 System.out.println(result.intValue()); 51 } 52 53 // 加法 54 public static void test2() { 55 BigDecimal bd1 = new BigDecimal(1.0);// 這個類沒有無參的構造器 56 BigDecimal bd2 = new BigDecimal(0.9); 57 58 BigDecimal result = bd1.add(bd2);// 做加法 59 60 System.out.println(result.floatValue());// 得到浮點類型 61 System.out.println(result.intValue()); 62 } 63 64 public static void test1() { 65 66 BigDecimal bd1 = new BigDecimal(1.0);// 這個類沒有無參的構造器 67 BigDecimal bd2 = new BigDecimal(0.9); 68 69 // 在計算時候沒有指定余下多少位小數和他的小數怎么進位就會報異常 70 // System.out.println(bd1.divide(bd2).setScale(2,BigDecimal.ROUND_HALF_UP));// 71 // 1/0.9->1.1111111 72 73 // bd1: 被除數 bd2: 除數 2:留下的幾位小數 ROUND_HALF_UP :四舍五入 74 System.out.println(bd1.divide(bd2, 2, BigDecimal.ROUND_HALF_UP));// 靜態常量所有字母大寫 75 76 // 一般涉及到比較敏感的金額不會用double 77 Double d1 = new Double(1.0); 78 Double d2 = new Double(0.9); 79 80 // 除法運算 81 // System.out.println(d1/d2); 82 // System.out.println(d1+d2); 83 // System.out.println(d1-d2); 84 // System.out.println(d1*d2); 85 } 86 87 }
下面具體講解
1 BigDecimal類處理高精度計算 2 Java在java.math包中提供的API類BigDecimal,用來對超過16位有效位的數進行精確的運算。雙精度浮點型變量double可以處理16位有效數,但在實際應用中,可能需要對更大或者更小的數進行運算和處理。一般情況下,對於那些不需要准確計算精度的數字,我們可以直接使用Float和Double處理,但是Double.valueOf(String) 和Float.valueOf(String)會丟失精度。所以開發中,如果我們需要精確計算的結果,則必須使用BigDecimal類來操作啦! 3 4 (一)BigDecimal類的常用的幾個構造方法 5 6 BigDecimal(int):將int表示形式轉換為BigDecimal對象 7 BigDecimal(String) :將字符串表示形式轉換為BigDecimal對象 8 BigDecimal(double):將double表示形式轉換為BigDecimal對象 9 (二)BigDecimal類的常用方法 10 11 add(BigDecimal):BigDecimal對象中的值相加,返回BigDecimal對象 12 subtract(BigDecimal):BigDecimal對象中的值相減,返回BigDecimal對象 13 multiply(BigDecimal):BigDecimal對象中的值相乘,返回BigDecimal對象 14 divide(BigDecimal):BigDecimal對象中的值相除,返回BigDecimal對象 15 toString():將BigDecimal對象中的值轉換成字符串 16 doubleValue():將BigDecimal對象中的值轉換成雙精度數 17 floatValue():將BigDecimal對象中的值轉換成單精度數 18 longValue():將BigDecimal對象中的值轉換成長整數 19 intValue():將BigDecimal對象中的值轉換成整數 20 21 //常用的;一般情況下,使用的都是四舍五入 22 BigDecimal.ROUND_HALF_UP表示四舍五入, 23 BigDecimal.ROUND_HALF_DOWN也是五舍六入, 24 BigDecimal.ROUND_UP表示進位處理(就是直接加1), 25 BigDecimal.ROUND_DOWN表示直接去掉尾數。 26 1: 加減乘除 27 BigDecimal bignum1 = new BigDecimal("10"); 28 BigDecimal bignum2 = new BigDecimal("5"); 29 BigDecimal bignum3 = null; 30 31 //加法 32 bignum3 = bignum1.add(bignum2); 33 System.out.println("和 是:" + bignum3); 34 35 //減法 36 bignum3 = bignum1.subtract(bignum2); 37 System.out.println("差 是:" + bignum3); 38 39 //乘法 40 bignum3 = bignum1.multiply(bignum2); 41 System.out.println("積 是:" + bignum3); 42 43 //除法 44 bignum3 = bignum1.divide(bignum2); 45 System.out.println("商 是:" + bignum3); 46 47 2: 比較大小 48 49 BigDecimal a = new BigDecimal (888); 50 BigDecimal b = new BigDecimal (666); 51 52 //使用compareTo方法比較 53 //注意:a、b均不能為null,否則會報空指針 54 if(a.compareTo(b) == -1){ 55 System.out.println("a小於b"); 56 } 57 58 if(a.compareTo(b) == 0){ 59 System.out.println("a等於b"); 60 } 61 62 if(a.compareTo(b) == 1){ 63 System.out.println("a大於b"); 64 } 65 66 if(a.compareTo(b) > -1){ 67 System.out.println("a大於等於b"); 68 } 69 70 if(a.compareTo(b) < 1){ 71 System.out.println("a小於等於b"); 72 73 // 四舍五入 保留兩位小數 74 new BigDecimal("1024.1234").setScale(2,BigDecimal.ROUND_HALF_UP); 75 76 77 78 //默認除法運算精度 79 private static final int DEF_DIV_SCALE = 10; 80 81 /** 82 * 提供精確的加法運算 83 * 84 * @param v1 被加數 85 * @param v2 加數 86 * @return 兩個參數的和 87 */ 88 89 public static double add(double v1, double v2) { 90 BigDecimal b1 = new BigDecimal(Double.toString(v1)); 91 BigDecimal b2 = new BigDecimal(Double.toString(v2)); 92 return b1.add(b2).doubleValue(); 93 } 94 95 /** 96 * 提供精確的加法運算 97 * 98 * @param v1 被加數 99 * @param v2 加數 100 * @return 兩個參數的和 101 */ 102 public static BigDecimal add(String v1, String v2) { 103 BigDecimal b1 = new BigDecimal(v1); 104 BigDecimal b2 = new BigDecimal(v2); 105 return b1.add(b2); 106 } 107 108 /** 109 * 提供精確的加法運算 110 * 111 * @param v1 被加數 112 * @param v2 加數 113 * @param scale 保留scale 位小數 114 * @return 兩個參數的和 115 */ 116 public static String add(String v1, String v2, int scale) { 117 if (scale < 0) { 118 throw new IllegalArgumentException( 119 "The scale must be a positive integer or zero"); 120 } 121 BigDecimal b1 = new BigDecimal(v1); 122 BigDecimal b2 = new BigDecimal(v2); 123 return b1.add(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString(); 124 } 125 126 /** 127 * 提供精確的減法運算 128 * 129 * @param v1 被減數 130 * @param v2 減數 131 * @return 兩個參數的差 132 */ 133 public static double sub(double v1, double v2) { 134 BigDecimal b1 = new BigDecimal(Double.toString(v1)); 135 BigDecimal b2 = new BigDecimal(Double.toString(v2)); 136 return b1.subtract(b2).doubleValue(); 137 } 138 139 /** 140 * 提供精確的減法運算。 141 * 142 * @param v1 被減數 143 * @param v2 減數 144 * @return 兩個參數的差 145 */ 146 public static BigDecimal sub(String v1, String v2) { 147 BigDecimal b1 = new BigDecimal(v1); 148 BigDecimal b2 = new BigDecimal(v2); 149 return b1.subtract(b2); 150 } 151 152 /** 153 * 提供精確的減法運算 154 * 155 * @param v1 被減數 156 * @param v2 減數 157 * @param scale 保留scale 位小數 158 * @return 兩個參數的差 159 */ 160 public static String sub(String v1, String v2, int scale) { 161 if (scale < 0) { 162 throw new IllegalArgumentException( 163 "The scale must be a positive integer or zero"); 164 } 165 BigDecimal b1 = new BigDecimal(v1); 166 BigDecimal b2 = new BigDecimal(v2); 167 return b1.subtract(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString(); 168 } 169 170 /** 171 * 提供精確的乘法運算 172 * 173 * @param v1 被乘數 174 * @param v2 乘數 175 * @return 兩個參數的積 176 */ 177 public static double mul(double v1, double v2) { 178 BigDecimal b1 = new BigDecimal(Double.toString(v1)); 179 BigDecimal b2 = new BigDecimal(Double.toString(v2)); 180 return b1.multiply(b2).doubleValue(); 181 } 182 183 /** 184 * 提供精確的乘法運算 185 * 186 * @param v1 被乘數 187 * @param v2 乘數 188 * @return 兩個參數的積 189 */ 190 public static BigDecimal mul(String v1, String v2) { 191 BigDecimal b1 = new BigDecimal(v1); 192 BigDecimal b2 = new BigDecimal(v2); 193 return b1.multiply(b2); 194 } 195 196 197 /** 198 * 提供精確的乘法運算 199 * 200 * @param v1 被乘數 201 * @param v2 乘數 202 * @param scale 保留scale 位小數 203 * @return 兩個參數的積 204 */ 205 public static double mul(double v1, double v2, int scale) { 206 BigDecimal b1 = new BigDecimal(Double.toString(v1)); 207 BigDecimal b2 = new BigDecimal(Double.toString(v2)); 208 return round(b1.multiply(b2).doubleValue(), scale); 209 } 210 211 /** 212 * 提供精確的乘法運算 213 * 214 * @param v1 被乘數 215 * @param v2 乘數 216 * @param scale 保留scale 位小數 217 * @return 兩個參數的積 218 */ 219 public static String mul(String v1, String v2, int scale) { 220 if (scale < 0) { 221 throw new IllegalArgumentException( 222 "The scale must be a positive integer or zero"); 223 } 224 BigDecimal b1 = new BigDecimal(v1); 225 BigDecimal b2 = new BigDecimal(v2); 226 return b1.multiply(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString(); 227 } 228 229 /** 230 * 提供(相對)精確的除法運算,當發生除不盡的情況時,精確到 231 * 小數點以后10位,以后的數字四舍五入 232 * 233 * @param v1 被除數 234 * @param v2 除數 235 * @return 兩個參數的商 236 */ 237 238 public static double div(double v1, double v2) { 239 return div(v1, v2, DEF_DIV_SCALE); 240 } 241 242 /** 243 * 提供(相對)精確的除法運算。當發生除不盡的情況時,由scale參數指 244 * 定精度,以后的數字四舍五入 245 * 246 * @param v1 被除數 247 * @param v2 除數 248 * @param scale 表示表示需要精確到小數點以后幾位。 249 * @return 兩個參數的商 250 */ 251 public static double div(double v1, double v2, int scale) { 252 if (scale < 0) { 253 throw new IllegalArgumentException("The scale must be a positive integer or zero"); 254 } 255 BigDecimal b1 = new BigDecimal(Double.toString(v1)); 256 BigDecimal b2 = new BigDecimal(Double.toString(v2)); 257 return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue(); 258 } 259 260 /** 261 * 提供(相對)精確的除法運算。當發生除不盡的情況時,由scale參數指 262 * 定精度,以后的數字四舍五入 263 * 264 * @param v1 被除數 265 * @param v2 除數 266 * @param scale 表示需要精確到小數點以后幾位 267 * @return 兩個參數的商 268 */ 269 public static String div(String v1, String v2, int scale) { 270 if (scale < 0) { 271 throw new IllegalArgumentException("The scale must be a positive integer or zero"); 272 } 273 BigDecimal b1 = new BigDecimal(v1); 274 BigDecimal b2 = new BigDecimal(v1); 275 return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).toString(); 276 } 277 278 /** 279 * 提供精確的小數位四舍五入處理 280 * 281 * @param v 需要四舍五入的數字 282 * @param scale 小數點后保留幾位 283 * @return 四舍五入后的結果 284 */ 285 public static double round(double v, int scale) { 286 if (scale < 0) { 287 throw new IllegalArgumentException("The scale must be a positive integer or zero"); 288 } 289 BigDecimal b = new BigDecimal(Double.toString(v)); 290 return b.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue(); 291 } 292 293 /** 294 * 提供精確的小數位四舍五入處理 295 * 296 * @param v 需要四舍五入的數字 297 * @param scale 小數點后保留幾位 298 * @return 四舍五入后的結果 299 */ 300 public static String round(String v, int scale) { 301 if (scale < 0) { 302 throw new IllegalArgumentException( 303 "The scale must be a positive integer or zero"); 304 } 305 BigDecimal b = new BigDecimal(v); 306 return b.setScale(scale, BigDecimal.ROUND_HALF_UP).toString(); 307 } 308 309 310 /** 311 * 取余數 312 * 313 * @param v1 被除數 314 * @param v2 除數 315 * @param scale 小數點后保留幾位 316 * @return 余數 317 */ 318 public static String remainder(String v1, String v2, int scale) { 319 if (scale < 0) { 320 throw new IllegalArgumentException( 321 "The scale must be a positive integer or zero"); 322 } 323 BigDecimal b1 = new BigDecimal(v1); 324 BigDecimal b2 = new BigDecimal(v2); 325 return b1.remainder(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString(); 326 } 327 328 /** 329 * 取余數 BigDecimal 330 * 331 * @param v1 被除數 332 * @param v2 除數 333 * @param scale 小數點后保留幾位 334 * @return 余數 335 */ 336 public static BigDecimal remainder(BigDecimal v1, BigDecimal v2, int scale) { 337 if (scale < 0) { 338 throw new IllegalArgumentException( 339 "The scale must be a positive integer or zero"); 340 } 341 return v1.remainder(v2).setScale(scale, BigDecimal.ROUND_HALF_UP); 342 } 343 344 /** 345 * 比較大小 346 * 347 * @param v1 被比較數 348 * @param v2 比較數 349 * @return 如果v1 大於v2 則 返回true 否則false 350 */ 351 public static boolean compare(String v1, String v2) { 352 BigDecimal b1 = new BigDecimal(v1); 353 BigDecimal b2 = new BigDecimal(v2); 354 int bj = b1.compareTo(b2); 355 boolean res; 356 if (bj > 0) 357 res = true; 358 else 359 res = false; 360 return res; 361 }
