Java BigDecimal 클래스 사용법 상세 정보

4974 단어 JavaBigDecimal
1. 인용문
'Effactive Java'라는 책의 말을 빌려 플로트와 더블 유형의 주요 설계 목표는 과학적 계산과 공학적 계산을 위한 것이다.그들은 2진 부동점 연산을 집행하는데, 이것은 광역 수치 범위에서 비교적 정확한 빠른 근사 계산을 제공하기 위해 정성껏 설계한 것이다.그러나 그것들은 완전히 정확한 결과를 제공하지 않았기 때문에 정확한 결과를 요구하는 장소에 사용되어서는 안 된다.그러나 상업 계산은 종종 결과가 정확해야 하기 때문에 이때 Big Decimal이 큰 도움이 된다.
2. BigDecimal 소개
BigDecimal은 임의의 정밀도의 정수 비표도값과 32비트의 정수 표도(scale)로 구성되어 있다.0이나 양이면 소수점 뒤의 자릿수를 나타냅니다.만약 음수라면, 이 수의 비표도값을 10의 음scale 차멱에 곱한다.따라서 BigDecimal이 나타내는 수치는 (unscaledValue× 10-scale).
3. 테스트 코드
3.1 구조 함수(주요 테스트 매개 변수 유형은 더블과 String의 두 가지 상용 구조 함수)
BigDecimal aDouble =new BigDecimal(1.22);
System.out.println("construct with a double value: " + aDouble);
BigDecimal aString = new BigDecimal("1.22");
System.out.println("construct with a String value: " + aString);
당신은 출력 결과가 무엇이라고 생각합니까?만약 당신이 첫 번째로 1.22를 출력할 것이라고 생각하지 않는다면, 당신이 맞힌 것을 축하합니다. 출력 결과는 다음과 같습니다.
construct with a doublevalue:1.2199999999999999733546474089962430298328399658203125
construct with a String value: 1.22
JDK 설명:
1. 매개 변수 유형이 더블인 구조 방법의 결과는 어느 정도 예측할 수 없는 것이다.어떤 사람들은 자바에 newBigDecimal(0.1)을 써서 만든 BigDecimal이 0.1(비표도값 1, 표도값 1)과 같다고 생각할 수 있지만, 실제로는 0.1000000000000055551123125727021815834541015625와 같다.이것은 0.1이 더블로 정확하게 표시할 수 없기 때문이다. (또는 이 상황에 대해 어떠한 유한한 길이의 2진 소수도 표시할 수 없기 때문이다.이렇게 하면 구조 방법에 전달된 값은 0.1과 같지 않을 것이다.
2. 다른 한편, String 구조 방법은 완전히 예측할 수 있다. newBigDecimal("0.1")을 쓰면 BigDecimal을 만들 것이다. 이것은 예상한 0.1과 같다.따라서 일반적으로 String 구조 방법을 우선적으로 사용하는 것이 좋습니다.
3. 더블이 BigDecimal의 원천으로 사용되어야 할 때 이 구조 방법은 정확한 전환을 제공했다는 것을 주의하십시오.이것은 Double를 먼저 사용하는 것과 같은 결과를 제공하지 않습니다.toString(double) 방법, 그리고 BigDecimal(String) 구조 방법을 사용하여 double를 String으로 변환합니다.이 결과를 얻으려면 static valueOf (double) 방법을 사용하십시오.
3.2 덧셈 조작
BigDecimal a =new BigDecimal("1.22");
System.out.println("construct with a String value: " + a);
BigDecimal b =new BigDecimal("2.22");
a.add(b);
System.out.println("aplus b is : " + a);
우리는 쉽게 출력할 것이라고 생각할 수 있다.
construct with a Stringvalue: 1.22
a plus b is :3.44
하지만 실제로는 a플러스 b is: 1.22
4. 원본 분석
4.1 valueOf(doubleval) 방법
public   static BigDecimal valueOf(double val) {
   // Reminder: a zero double returns '0.0', so we cannotfastpath
   // to use the constant ZERO. This might be important enough to
   // justify a factory approach, a cache, or a few private
   // constants, later.
   returnnew BigDecimal(Double.toString(val));// 3.1 JDK
}
4.2 add(BigDecimal augend) 방법

public BigDecimal  add(BigDecimal augend) {
  long xs =this.intCompact; // BigDecimal, a intCompact 122
  long ys = augend.intCompact;// 
  BigInteger fst = (this.intCompact !=INFLATED) ?null :this.intVal;// BigInteger ,intVal BigDecimal BigInteger 
  BigInteger snd =(augend.intCompact !=INFLATED) ?null : augend.intVal;
  int rscale =this.scale;// 

  long sdiff = (long)rscale - augend.scale;// 

  if (sdiff != 0) {// 
   if (sdiff < 0) {
     int raise =checkScale(-sdiff);
     rscale =augend.scale;
     if (xs ==INFLATED ||
       (xs = longMultiplyPowerTen(xs,raise)) ==INFLATED)
       fst =bigMultiplyPowerTen(raise);
    }else {
      int raise =augend.checkScale(sdiff);
      if (ys ==INFLATED ||(ys =longMultiplyPowerTen(ys,raise)) ==INFLATED)
        snd = augend.bigMultiplyPowerTen(raise);
    }
  }

  if (xs !=INFLATED && ys !=INFLATED) {
   long sum = xs + ys;
   if ( (((sum ^ xs) &(sum ^ ys))) >= 0L)// 
     return BigDecimal.valueOf(sum,rscale);// BigDecimal BigDecimal 
  }
  if (fst ==null)
    fst =BigInteger.valueOf(xs);//BigInteger 

  if (snd ==null)
    snd =BigInteger.valueOf(ys);

  BigInteger sum =fst.add(snd);
  return (fst.signum == snd.signum) ?new BigDecimal(sum,INFLATED, rscale, 0) :
   new BigDecimal(sum,compactValFor(sum),rscale, 0);// BigDecimal 
}

이상은 덧셈 원본에 대한 분석일 뿐이다. 감승제는 결국 새로운 BigDecimal 대상으로 되돌아온다. 왜냐하면 BigInteger와 BigDecimal은 모두 변할 수 없는(immutable)이기 때문에 매 단계의 연산을 할 때 새로운 대상이 생기기 때문에 a.add(b).덧셈 조작을 했지만 a는 덧셈 조작 후의 값을 저장하지 않았습니다. 정확한 용법은 a=a.add(b)입니다.
5. 요약
(1) 비즈니스 컴퓨팅은 BigDecimal을 사용합니다.
(2) 매개변수 유형이 String인 구조 함수를 최대한 사용합니다.
(3) BigDecimal은 모두 변할 수 없는 (immutable) 것으로 매 단계의 연산을 진행할 때 새로운 대상이 생기기 때문에 가감곱하기 연산을 할 때 절대로 조작 후의 값을 저장해야 한다.
(4) 우리는 종종 JDK 밑바닥의 일부 실현 세부 사항을 소홀히 하여 오류를 초래하기 쉬우므로 더욱 주의해야 한다.
참고:클래스 BigDecimal

좋은 웹페이지 즐겨찾기