자바 BigDecimal 큰 숫자 조작
18475 단어 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 입 니 다.
효과 자바 라 는 책 에서 도 이 원칙 을 언급 했다. 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
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
실수의 표현방식 - 부동소수점(IEEE 754)지수부 무한 소수, 혹은 엄청 긴 소수점을 가지는 실수는 오차를 낼 수 밖에 없습니다. 아래 부동소수점으로 표현하는 방식을 보면 알 수 있습니다. 소수점의 이동 칸 수 + bios => 지수부 지수부(8bit) 가수...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.