Big Decimal - new 또는 value Of를 사용합니다.
Big Decimal 객체를 더블 d에서 꺼내는 방법은 두 가지가 있습니다.
new BigDecimal(d)
BigDecimal.valueOf(d)
어떤 방법이 더 좋을까요?그럴 것이다valueOf
새 개체를 생성하시겠습니까?
일반적으로 (Big Decimal뿐만 아니라) 새로운 것과 value Of 중 무엇을 권장합니까?
다음 두 가지 질문이 있습니다. "무엇에 사용해야 합니까?BigDecimal
?" 및 "일반적으로 무엇을 해야 합니까?"
위해서BigDecimal
: 이것은 조금 까다롭습니다. 왜냐하면 그들은 같은 일을 하지 않기 때문입니다.는 의 표준 표현을 사용합니다.double
를 인스턴스화하기 위해 전달된 값BigDecimal
물건.즉, 다음과 같습니다.의 값BigDecimal
할 때 보이는 것이 오브젝트입니다.System.out.println(d)
.
단, 를 사용하는 경우BigDecimal
를 대표하려고 합니다.double
가능한 한 정확하게 값을 매길 수 있습니다.이렇게 하면 보통 원하는 것보다 훨씬 더 많은 숫자가 저장됩니다.엄밀히 말하면, 그것은 보다 더 정확하다.valueOf()
단, 직관성이 떨어집니다.
JavaDoc에는 이에 대한 좋은 설명이 있습니다.
이 생성자의 결과는 다소 예측할 수 없습니다.어떤 이는 글쓰기가
new BigDecimal(0.1)
Java에서 작성한다.BigDecimal
이 값은 0.1(스케일1의 스케일1의 비스케일값)과 정확히 일치하지만 실제로는 0.14500000000055111512312578270211883404541015625와 같습니다.이는 0.1을 정확하게 표현할 수 없기 때문입니다.double
(또는 유한한 길이의 2진수 분수로 한다.)따라서 컨스트럭터에 전달되는 값은 외관상으로는 0.1과 완전히 동일하지 않습니다.
일반적으로 결과가 동일한 경우(즉, 결과가 동일하지 않은 경우)BigDecimal
(단, 그 외의 경우는 대부분)valueOf()
권장: 공통값( 참조)의 캐시를 실행할 수 있으며, 발신자를 변경하지 않아도 캐싱 동작을 변경할 수 있습니다. new
는 필요하지 않은 경우에도 항상 새로운 값을 인스턴스화합니다(최적의 예:new Boolean(true)
대.Boolean.valueOf(true)
).
를 사용하고 있는 경우BigDecimal
통화 가치를 저장하는 개체는 계산에 이중 값을 포함하지 않는 것이 좋습니다.
또 다른 답변에서도 언급했듯이 이중값으로 인해 정확도 문제가 발생하며 이러한 문제가 자주 발생합니다.
일단 그것을 통과하면, 당신의 질문에 대한 답은 간단하다.생성자에 대한 인수로 String 값을 가진 생성자 메서드를 항상 사용하십시오. 생성자에 대한 인수에는 이 메서드가 없습니다.valueOf
의 방법String
.
증명이 필요한 경우 다음을 시도해 보십시오.
BigDecimal bd1 = new BigDecimal(0.01);
BigDecimal bd2 = new BigDecimal("0.01");
System.out.println("bd1 = " + bd1);
System.out.println("bd2 = " + bd2);
다음과 같은 출력이 표시됩니다.
bd1 = 0.01000000000000000020816681711721685132943093776702880859375
bd2 = 0.01
관련 질문도 참조해 주세요.
기본적으로 valueOf(double val)는 다음을 수행합니다.
return new BigDecimal(Double.toString(val));
따라서 -> 네, 새로운 오브젝트가 생성됩니다. : )
일반적으로 당신의 코딩 스타일에 따라 다르다고 생각합니다.value Of와 new가 같은 결과라면 혼재하지 않겠습니다.
서문
부동소수점 유형, 숫자 및 산술에 대해 논의하는 이유는 무엇입니까?간단하죠.우리는 10번 베이스로 계산하지만 기계는 2번 베이스로 계산됩니다.
Big Decimal - 정확한 표현 필요(근사가 아님)
사용하시는 경우BigDecimal
즉, 이 명령어를 정확하게 표현해야 합니다.0.1
그리고 10의 다른 음의 거듭제곱(보통 당신은 십진수와 관련된 돈이나 산수를 다루고 있을 것이다).
Double은 문제를 의미합니다(Big Decimal과 관련된 경우).
다음 조작을 하는 에는 조작을 할 필요가 있는 경우에는 조작을 해 주십시오.double
을 (float)로 설정합니다.BigDecimal
두 되는데, 그 왜냐하면 그것은 대변하는 것이 불가능하기 때문입니다.0.1
베이스 2의 2루타로 말이야기계는 "저장"됩니다(부동 소수점 산술의 경우 IEEE-754 표준). 2배입니다.여기 실제로 무슨 일이 일어나고 있는지에 대한 좋은 설명이 있습니다.)던컨의 대답은 내가 말하고자 하는 것과 무엇을 해야 하고 하지 말아야 한다는 것을 보여준다.
0.1을 정확하게 저장할 수 있다고 생각하는 프로그래밍 언어는 실제로는 그렇지 않습니다.그것은 단지 근사치일 뿐이다.
System.out.println(0.1d);
//Prints 0.1 or so you think ;-)
//If you are not convinced, try this:
double x = 1.1; double y = 1.0;
if (x-y == 0.1) {// print true } else {// print false}
//or perhaps this:
double amount1 = 2.15;
double amount2 = 1.10;
System.out.println("Difference: " + (amount1 - amount2));
예
double smallD = 0.0001;
double smallDNoScientificNotation = 0.001; //>= 10E-3
double normalD = 10.345678;
double bigDNoScientificNotation = 1234567.123456789; //<=10E7
double bigD = 56_789_123_456_789.123456789;
//double
System.out.println(smallD); //1.0E-4, computerized scientific notation, this is how Double toString works
System.out.println(smallDNoScientificNotation); //0.001, OK
System.out.println(normalD); //10.345678, OK
System.out.println(bigDNoScientificNotation); //1234567.123456789, OK
System.out.println(bigD); //5.6789123456789125E13, computerized scientific notation, this is how Double toString works
//new BigDecimal(double): not OK, don't use! Attempting to representing the base-2 representation as accurately as possible
System.out.println(new BigDecimal(smallD)); //0.000100000000000000004792173602385929598312941379845142364501953125
System.out.println(new BigDecimal(smallDNoScientificNotation)); //0.001000000000000000020816681711721685132943093776702880859375
System.out.println(new BigDecimal(normalD)); //10.34567799999999948568074614740908145904541015625
System.out.println(new BigDecimal(bigDNoScientificNotation)); //1234567.12345678894780576229095458984375
System.out.println(new BigDecimal(bigD)); //56789123456789.125
//BigDecimal.valueOf (Dont use if the range is >= 10E-3, >= 10E7), under the hood it's using Double.toString
System.out.println(BigDecimal.valueOf(smallD)); //0.00010 - notice the extra 0, stemming from 1.0E-4
System.out.println(BigDecimal.valueOf(smallDNoScientificNotation)); //0.001
System.out.println(BigDecimal.valueOf(normalD)); //10.345678
System.out.println(BigDecimal.valueOf(bigDNoScientificNotation)); //1234567.123456789
System.out.println(BigDecimal.valueOf(bigD)); //56789123456789.125 //loss of accuracy
컴퓨터화된 과학적 표기법 - 여기에 더 있습니다.
보너스 1 - 함정
보너스 2 - 자바 제3판 유효 (Joshua Bloch)
항목 60: 정확한 답변이 필요한 경우 부동 또는 이중화를 피하십시오.
부동형과 이중형은 0.1(또는 10의 다른 음의 거듭제곱)을 부동형 또는 정확히 두 배로 나타낼 수 없기 때문에 금전적 계산에 특히 적합하지 않습니다.
:
그러나 Big Decimal을 사용하는 데는 두 가지 단점이 있습니다. 즉, 기본 산술 유형을 사용하는 것보다 훨씬 편리하지 않고 훨씬 느립니다.후자의 단점은 당신이 하나의 짧은 문제를 풀 때 상관이 없지만, 전자는 당신을 짜증나게 할 수 있다.
:
Big Decimal을 사용하는 대신 int 또는 long을 사용하여 관련된 양에 따라 소수점을 직접 추적하는 방법도 있습니다.이 예에서 분명한 접근법은 모든 계산을 센트로 하는 것입니다.
수학적인 성향을 가진 사람들을 위한 추가 읽기;-)
부동 소수점 산술에 대해 컴퓨터 과학자가 알아야 할 사항
언급URL : https://stackoverflow.com/questions/7186204/bigdecimal-to-use-new-or-valueof
'programing' 카테고리의 다른 글
C#의 문자열에서 함수를 호출한다. (0) | 2022.11.07 |
---|---|
MySQL의 기존 행에 대한 삽입 문 가져오기 (0) | 2022.11.07 |
Mariadb Docker 컨테이너가 데이터베이스 스키마를 사용한 초기화를 거부함 (0) | 2022.11.07 |
PHP: memory_limits > 1024M 설정이 작동하지 않음 (0) | 2022.11.07 |
슈퍼클래스 컨스트럭터를 명시적으로 호출해야 하는 경우는 언제입니까? (0) | 2022.11.07 |