자바 BigDecimal 큰 숫자 조작

18475 단어 BigDecimal
자바 에 서 는 자바. math. binInteger 류 와 자바. math. bigDecimal 류 를 큰 숫자 로 제공 합 니 다.이 두 가지 유형 은 높 은 정밀도 계산 에 사용 되 는데 그 중에서 BigInteger 류 는 큰 정수 에 대한 처리 류 이 고 BigDecimal 류 는 큰 소수 에 대한 처리 류 이다.
BigDecimal                                                                               
BigDecimal 의 실현 은 BigInteger 에 이 용 됐 고, 다른 것 은 BigDecimal 이 소수 개념 을 넣 었 다 는 것 이다.일반적인 float 형 과 Double 형 데 이 터 는 과학적 인 계산 이나 공정 계산 에 만 사용 할 수 있 습 니 다. 상업 계산 에서 요구 하 는 디지털 정밀도 가 비교적 높 기 때문에 자바. math. bigDecimal 류 를 사용 해 야 합 니 다. 이 는 모든 정밀도 의 고정 점 수 를 지원 하고 이 를 통 해 화폐 값 을 정확하게 계산 할 수 있 습 니 다.아래 에서 우 리 는 예 를 들 어 그것 의 용법 을 간단하게 소개 한다.
java.math.BigDecimal                                                             
1, BigInteger 는 java. math. BigInteger 에 속 하기 때문에 매번 사용 하기 전에 import 클래스 를 사용 해 야 합 니 다.우연히 import 를 잊 어 버 려 서 알림 부 호 를 찾 지 못 했 습 니 다.
2. 그 구조 방법 은 매우 많 지만 지금 은 가끔 사용 하 는 것 이 있다.
BigInteger(String val)

BigInteger 의 10 진 문자열 표시 형식 을 BigInteger 로 변환 합 니 다.
BigInteger(String val, int radix)

지정 한 기수 인 BigInteger 의 문자열 표시 형식 을 BigInteger 로 변환 합 니 다.
int 형 2 를 BigInteger 형 으로 바 꾸 려 면
BigInteger two=new BigInteger("2"); //注意2双引号不能省略

3. BigInteger 류 는 add () = '+', divide () = '-' 등 모든 int 형 수학 조작 을 모 의 했 으 나 그 내용 을 수학 연산 할 때 수학 연산 자 를 직접 사용 하여 연산 할 수 없 으 므 로 내부 방법 을 사용 해 야 한다.그리고 그 조작 수도 빅 인 터 거 형 이 어야 한다.
예 를 들 어 to. add (2) 는 잘못된 조작 입 니 다. 2 는 BigInteger 형 으로 변 하지 않 았 기 때 문 입 니 다.
4. 계산 결 과 를 출력 하려 면 'toString' 방법 으로 10 진수 문자열 로 변환 해 야 합 니 다. 자세 한 설명 은 다음 과 같 습 니 다.
String toString()

이 BigInteger 의 10 진 문자열 표시 형식 을 되 돌려 줍 니 다.출력 방법:
System.out.print(two.toString());

5. 세 개의 함 수 를 따로 설명 합 니 다. 
BigInteger remainder(BigInteger val)

값 이 (this% val) 인 BigInteger 를 되 돌려 줍 니 다.
BigInteger negate()

값 을 되 돌려 주 는 것 은 (- tis) 의 BigInteger 입 니 다.
int compareTo(BigInteger val)

이 BigInteger 를 지정 한 BigInteger 와 비교 합 니 다.
remainder 는 여 수 를 구 하 는 데 쓰 인 다.negate 는 조작 수 를 반대 수로 바 꿉 니 다.compare 의 상세 한 설명 은 다음 과 같다.
public int compareTo(BigInteger val)

이 BigInteger 를 지정 한 BigInteger 와 비교 합 니 다.6 개의 불 비교 연산 자 (<, =, >, > =,! =, < =) 중의 모든 연산 자 에 대한 각 방법 에 대해 우선 이 방법 을 제공 합 니 다.이러한 비 교 를 실행 하 는 건의 문 구 는 다음 과 같다. (x. compare To (y) < op > 0) 그 중에서 < op > 은 여섯 개의 비교 연산 자 중 하나 이다.
지정 자:
인터페이스 Comparable < BigInteger > 의 compare To
인자:
val - 이 BigInteger 를 비교 한 BigInteger.
자바 에서 부동 소수점 의 정확 한 계산 을 실현 하 다.                                                       
문제 의 제기: 
만약 우리 가 아래 프로그램 을 컴 파일 해서 실행 한다 면 무엇 을 볼 수 있 습 니까?
public   class   Test{   

          public   static   void   main(String   args[]){   

                  System.out.println(0.05+0.01);   

                  System.out.println(1.0-0.42);   

                  System.out.println(4.015*100);   

                  System.out.println(123.3/100);   

          }   

  };

잘못 본 거 아니 야!결 과 는 확실 하 다. 
0.060000000000000005  

  0.5800000000000001  

  401.49999999999994  

  1.2329999999999999

자바 의 간단 한 부동 소수점 형식 인 float 와 double 은 연산 할 수 없습니다.자바 뿐만 아니 라 다른 많은 프로 그래 밍 언어 에서 도 이런 문제 가 있다.대부분의 경우 계산 결 과 는 정확 하지만 몇 번 더 시도 하면 위 와 같은 오 류 를 시도 할 수 있다.이 제 는 왜 BCD 코드 가 있어 야 하 는 지 이해 하 게 되 었 다. 
이 문 제 는 상당히 심각 하 다. 만약 당신 이 9.999999999999 위안 이 있다 면, 당신 의 컴퓨터 는 당신 이 10 위안 의 상품 을 구 매 할 수 있다 고 생각 하지 않 을 것 이다. 
어떤 프로 그래 밍 언어 에 서 는 이러한 상황 을 처리 하기 위해 전문 적 인 화폐 유형 을 제공 하지만 자바 에는 없다.이제 이 문 제 를 어떻게 해결 하 는 지 봅 시다. 
반올림
우리 의 첫 번 째 반응 은 반올림 을 하 는 것 이다.Math 클래스 의 round 방법 은 몇 자리 의 소 수 를 유지 하 는 것 을 설정 할 수 없습니다. 우 리 는 이렇게 (두 자리 유지) 할 수 밖 에 없습니다. 
public   double   round(double   value){   

          return   Math.round(value*100)/100.0;   

  }

불행 하 게 도 위의 코드 는 정상적으로 작 동 하지 않 습 니 다. 이 방법 에 4.015 를 입력 하면 4.02 가 아니 라 4.01 로 돌아 갑 니 다. 예 를 들 어 우리 가 위 에서 본 것 과 같 습 니 다. 
4.015*100=401.49999999999994

따라서 우리 가 정확 한 반올림 을 하려 면 간단 한 유형 을 이용 하여 어떠한 연산 도 해 서 는 안 된다. 
java. text. decimalFormat 도 이 문 제 를 해결 할 수 없습니다.
System.out.println(new   java.text.DecimalFormat("0.00").format(4.025));

출력 은 4.02 입 니 다. 
  • BigDecimal 

  • 효과   자바 라 는 책 에서 도 이 원칙 을 언급 했다. float 와 double 은 과학적 계산 이나 공정 계산 에 만 사용 할 수 있 고 상업 계산 에서 우 리 는 자바. math. BigDecimal 을 사용 해 야 한다.BigDecimal 은 모두 4 개의 만 들 수 있 는 방법 이 있 습 니 다. 우 리 는 BigInteger 로 만 들 수 있 는 두 가지 에 관심 이 없습니다. 그러면 두 가지 가 있 습 니 다. 그들 은: 
    BigDecimal(double   val)     
    
    // Translates   a   double   into   a   BigDecimal.     
    
    BigDecimal(String   val)     
    
    // Translates   the   String   repre   sentation   of   a   BigDecimal   into   a   BigDecimal.

    위의 API 는 간략하게 설명 하 는 것 이 상당히 명확 하고 일반적인 상황 에서 위의 하 나 는 사용 하기에 편리 해 야 한다.우 리 는 생각 도 하지 않 고 썼 을 지도 모 르 는데 무슨 문제 가 있 을 까?문제 가 생 겼 을 때 위 에서 만 들 수 있 는 방법 에 대한 상세 한 설명 중 하 나 를 발견 할 수 있 습 니 다. 정확 한 계산 이 필요 하 다 면 String 으로 BigDecimal 을 만 들 지 않 으 면 안 된다 는 뜻 으로 이해 할 수 있 습 니 다!효과   자바 라 는 책의 예 는 String 으로 BigDecimal 을 만 들 수 있 지만 책 에 서 는 이 점 을 강조 하지 않 았 다. 작은 실수 일 수도 있다. 
    해결 방안 
    이제 우 리 는 이 문 제 를 해결 할 수 있 습 니 다. 원칙 은 BigDecimal 을 사용 하고 반드시 String 으로 충분히 만들어 야 한 다 는 것 입 니 다.  
    하지만 상상 해 보 세 요. 만약 에 우리 가 덧셈 연산 을 하려 면 두 개의 부동 점 수 를 String 으로 바 꾼 다음 에 BigDecimal 을 만 들 수 있 습 니 다. 그 중 하 나 는 add 방법 을 호출 하여 다른 하 나 를 매개 변수 로 한 다음 에 연산 결과 (BigDecimal) 를 부동 소수점 으로 바 꿔 야 합 니 다.너 는 이렇게 번 거 로 운 과정 을 참 을 수 있 니?다음은 도구 류 Arith 를 제공 하여 조작 을 간소화 합 니 다.이것 은 가감 승제 와 반올림 을 포함 하여 다음 과 같은 정적 방법 을 제공 합 니 다.
    public   static   double   add(double   v1,double   v2)   
    
    public   static   double   sub(double   v1,double   v2)   
    
    public   static   double   mul(double   v1,double   v2)   
    
    public   static   double   div(double   v1,double   v2)   
    
    public   static   double   div(double   v1,double   v2,int   scale)   
    
    public   static   double   round(double   v,int   scale)
    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();   
    
              }   
    
      };

    나 는 천 왕 개 지 호의 분할 선 이다.                                                                 
     
     
    참고:http://jeelee.iteye.com/blog/652003

    좋은 웹페이지 즐겨찾기