java.math.BigDecimal、BinInteger类的用法(用于精确运算)

在java中提供了大数字的操作类,即java.math.BinInteger类和java.math.BigDecimal类。这两个类用于高精度计 算,其中BigInteger类是针对大整数的处理类,而BigDecimal类则是针对大小数的处理类。

1,BigInteger属于java.math.BigInteger,因此在每次使用前都要import 这个类。
2,其构造方法有很多,但现在偶用到的有: 
BigInteger(String val) 
          将 BigInteger 的十进制字符串表示形式转换为 BigInteger。 
BigInteger(String val, int radix) 
          将指定基数的 BigInteger 的字符串表示形式转换为 BigInteger。 
如要将int型的2转换为BigInteger型,要写为BigInteger two=new BigInteger("2"); //注意2双引号不能省略 

3,BigInteger类模拟了所有的int型数学操作,如add()==“+”,divide()==“-”等,但注意其内容进行数学运算时不能直接使用数学运算符进行运算,必须使用其内部方法。而且其操作数也必须为BigInteger型。 
如:two.add(2)就是一种错误的操作,因为2没有变为BigInteger型。 

4,当要把计算结果输出时应该使用.toString方法将其转换为10进制的字符串,详细说明如下: 
String toString() 
          返回此 BigInteger 的十进制字符串表示形式。 
输出方法:System.out.print(two.toString()); 

5,另外说明三个个用到的函数。   
BigInteger remainder(BigInteger val) 
          返回其值为 (this % val) 的 BigInteger。 
BigInteger negate() 
          返回其值是 (-this) 的 BigInteger。 
int        compareTo(BigInteger val) 
          将此 BigInteger 与指定的 BigInteger 进行比较。 
remainder用来求余数。 
negate将操作数变为相反数。 
compare的详解如下: 
compareTo 

public int compareTo(BigInteger val) 

    将此 BigInteger 与指定的 BigInteger 进行比较。对于针对六个布尔比较运算符 (<, ==, >, >=, !=, <=) 中的每一个运算符的各个方法,优先提供此方法。执行这些比较的建议语句是:(x.compareTo(y) <op> 0),其中 <op> 是六个比较运算符之一。



Java中的简单浮点数类型float和double不能够进行运算。不光是Java,在其它很多编程语言中也有这样的问题。在大多数情况下,计算的结果是准确的,但是多试几次(可以做一个循环)就可以试出类似上面的错误。现在终于理解为什么要有BCD码了。   
  这个问题相当严重,如果你有9.999999999999元,你的计算机是不会认为你可以购买10元的商品的。   
  在有的编程语言中提供了专门的货币类型来处理这种情况,但是Java没有。现在让我们看看如何解决这个问题。   
    
      
    
  四舍五入   
  我们的第一个反应是做四舍五入。Math类中的round方法不能设置保留几位小数,我们只能象这样(保留两位):   
  public   double   round(double   value){   
          return   Math.round(value*100)/100.0;   
  }   
    
  非常不幸,上面的代码并不能正常工作,给这个方法传入4.015它将返回4.01而不是4.02,如我们在上面看到的   
  4.015*100=401.49999999999994   
  因此如果我们要做到精确的四舍五入,不能利用简单类型做任何运算   
  java.text.DecimalFormat也不能解决这个问题:   
  System.out.println(new   java.text.DecimalFormat("0.00").format(4.025));   
  输出是4.02   
  在《Effective   Java》这本书中也提到这个原则,float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用java.math.BigDecimal。    
        import   java.math.BigDecimal;   
  /**   
    *   由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精   
    *   确的浮点数运算,包括加减乘除和四舍五入。   
    */   
    
  public   class   Arith{   
    
          //默认除法运算精度   
          private   static   final   int   DEF_DIV_SCALE   =   10;   
    
    
          //这个类不能实例化   
          private   Arith(){   
          }   
    
      
          /**   
            *   提供精确的加法运算。   
            *   @param   v1   被加数   
            *   @param   v2   加数   
            *   @return   两个参数的和   
            */   
    
          public   static   double   add(double   v1,double   v2){   
                  BigDecimal   b1   =   new   BigDecimal(Double.toString(v1));   
                  BigDecimal   b2   =   new   BigDecimal(Double.toString(v2));   
                  return   b1.add(b2).doubleValue();   
          }   
    
          /**   
            *   提供精确的减法运算。   
            *   @param   v1   被减数   
            *   @param   v2   减数   
            *   @return   两个参数的差   
            */   
    
          public   static   double   sub(double   v1,double   v2){   
                  BigDecimal   b1   =   new   BigDecimal(Double.toString(v1));   
                  BigDecimal   b2   =   new   BigDecimal(Double.toString(v2));   
                  return   b1.subtract(b2).doubleValue();   
          }     
    
          /**   
            *   提供精确的乘法运算。   
            *   @param   v1   被乘数   
            *   @param   v2   乘数   
            *   @return   两个参数的积   
            */   
    
          public   static   double   mul(double   v1,double   v2){   
                  BigDecimal   b1   =   new   BigDecimal(Double.toString(v1));   
                  BigDecimal   b2   =   new   BigDecimal(Double.toString(v2));   
                  return   b1.multiply(b2).doubleValue();   
          }   
    
      
    
          /**   
            *   提供(相对)精确的除法运算,当发生除不尽的情况时,精确到   
            *   小数点以后10位,以后的数字四舍五入。   
            *   @param   v1   被除数   
            *   @param   v2   除数   
            *   @return   两个参数的商   
            */   
    
          public   static   double   div(double   v1,double   v2){   
                  return   div(v1,v2,DEF_DIV_SCALE);   
          }   
    
      
    
          /**   
            *   提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指   
            *   定精度,以后的数字四舍五入。   
            *   @param   v1   被除数   
            *   @param   v2   除数   
            *   @param   scale   表示表示需要精确到小数点以后几位。   
            *   @return   两个参数的商   
            */   
    
          public   static   double   div(double   v1,double   v2,int   scale){   
                  if(scale<0){   
                          throw   new   IllegalArgumentException(   
                                  "The   scale   must   be   a   positive   integer   or   zero");   
                  }   
                  BigDecimal   b1   =   new   BigDecimal(Double.toString(v1));   
                  BigDecimal   b2   =   new   BigDecimal(Double.toString(v2));   
                  return   b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();   
          }   
    
      
    
          /**   
            *   提供精确的小数位四舍五入处理。   
            *   @param   v   需要四舍五入的数字   
            *   @param   scale   小数点后保留几位   
            *   @return   四舍五入后的结果   
            */   
    
          public   static   double   round(double   v,int   scale){   
                  if(scale<0){   
                          throw   new   IllegalArgumentException(   
                                  "The   scale   must   be   a   positive   integer   or   zero");   
                  }   
                  BigDecimal   b   =   new   BigDecimal(Double.toString(v));   
                  BigDecimal   one   =   new   BigDecimal("1");   
                  return   b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();   
          }   
  }; 

此异常表明 MyBatis 在尝试为 `Object[]` 数组寻找合适的构造函数,但未找到匹配的构造函数。`Object[]` 是一个数组型,本身不存在接收多个特定型参数的构造函数。以下是一些解决办法: ### 1. 直接使用数组元素 在 Mapper XML 文件或者注解 SQL 里,直接使用数组的元素,而非尝试把数组当作一个对象来处理。 ```xml <select id="yourMethod" resultType="YourResultType"> SELECT * FROM your_table WHERE column1 = #{array[0]} AND column2 = #{array[1]} AND ... </select> ``` 在 Java 代码中,可按如下方式调用: ```java List<Object[]> paramList = new ArrayList<>(); // 添加数据到 paramList yourMapper.yourMethod(paramList); ``` ### 2. 封装为自定义对象 把 `Object[]` 数组封装成自定义对象,如此 MyBatis 就能使用自定义对象的构造函数或者 setter 方法。 ```java public class YourCustomObject { private String field1; private String field2; private BigDecimal field3; // 其他字段 // 构造函数 public YourCustomObject(String field1, String field2, BigDecimal field3, ...) { this.field1 = field1; this.field2 = field2; this.field3 = field3; // 初始化其他字段 } // Getter 和 Setter 方法 public String getField1() { return field1; } public void setField1(String field1) { this.field1 = field1; } // 其他 Getter 和 Setter 方法 } ``` 在 Java 代码里,将 `Object[]` 转换为 `YourCustomObject`: ```java List<YourCustomObject> customObjectList = new ArrayList<>(); for (Object[] array : paramList) { YourCustomObject customObject = new YourCustomObject((String) array[0], (String) array[1], (BigDecimal) array[2], ...); customObjectList.add(customObject); } yourMapper.yourMethod(customObjectList); ``` 在 Mapper XML 文件或者注解 SQL 中,使用自定义对象的属性: ```xml <select id="yourMethod" resultType="YourResultType"> SELECT * FROM your_table WHERE column1 = #{field1} AND column2 = #{field2} AND ... </select> ``` ### 3. 使用 Map 把 `Object[]` 数组转换为 `Map`,这样 MyBatis 就能使用 `Map` 的键值对。 ```java List<Map<String, Object>> mapList = new ArrayList<>(); for (Object[] array : paramList) { Map<String, Object> map = new HashMap<>(); map.put("field1", array[0]); map.put("field2", array[1]); map.put("field3", array[2]); // 其他键值对 mapList.add(map); } yourMapper.yourMethod(mapList); ``` 在 Mapper XML 文件或者注解 SQL 中,使用 `Map` 的键: ```xml <select id="yourMethod" resultType="YourResultType"> SELECT * FROM your_table WHERE column1 = #{field1} AND column2 = #{field2} AND ... </select> ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值