• 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     }
  • 相关阅读:
    2013面试C++小结
    Linux C 面试题总结 .
    [SCOI2011]糖果
    python——简单爬虫
    python——ADSL拨号程序
    python——处理xls表格
    Vsphere初试——架设Panabit行为管理
    Vsphere初试——使用Vsphere client
    Vsphere初试——基本安装
    Python2与Python3的不同点
  • 原文地址:https://www.cnblogs.com/dabu/p/12411945.html
Copyright © 2020-2023  润新知