java里面的高精度运算
Posted 代码吴彦祖
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java里面的高精度运算相关的知识,希望对你有一定的参考价值。
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 }
以上是关于java里面的高精度运算的主要内容,如果未能解决你的问题,请参考以下文章