위도/경도에 BigDecimal을 사용해야하는 XSD이 있습니다. 나는 현재 double/lon을 double 형으로 가지고 BigDecimal로 변환하지만 약 12 개 정도의 정밀도를 사용해야합니다. 나는 그것을 설정하는 방법을 알아낼 수 없었다. 아무도 이것으로 나를 도울 수 있습니까?BigDecimal의 특정 정밀도 설정
답변
setScale()과 같이 사용할 수 있습니다.
double d = ...
BigDecimal db = new BigDecimal(d).setScale(12, BigDecimal.ROUND_HALF_UP);
질문의 제목은 정밀도에 대해 묻습니다. BigDecimal은 배율과 정밀도를 구분합니다. Scale은 소수 자릿수입니다. 정밀도는 유효 숫자라고도하는 significant figures의 수로 생각할 수 있습니다.
Clojure의 몇 가지 예입니다.
(.scale 0.00123M) ; 5
(.precision 0.00123M) ; 3
(Clojure의에서
M
는 BigDecimal를 당신이 좋아하는 경우에 당신은 자바에 Clojure를 번역 할 수 있습니다. 문자 지정,하지만 난 그것을 자바보다 더 컴팩트하게 찾을 수 있습니다!)
, 다음 작업을 쉽게 할 수 있습니다 규모 증가 :
(.setScale 0.00123M 7) ; 0.0M
을하지만 당신은 할 수 없습니다 감소 동일한 방법으로 규모 :
3,516,
(.setScale 0.00123M 3) ; ArithmeticException Rounding necessary
당신은 너무 반올림 모드를 통과해야합니다 :
(.setScale 0.00123M 3 BigDecimal/ROUND_HALF_EVEN) ;
; Note: BigDecimal would prefer that you use the MathContext rounding
; constants, but I don't have them at my fingertips right now.
그래서, 그 규모를 쉽게 변경할 수 있습니다. 그러나 정밀도는 어떻습니까? 희망만큼 쉬운 것은 아닙니다!
그것은 정밀도감소에 쉽게 :
(.round 3.14159M (java.math.MathContext. 3)) ; 3.14M
그러나이 방법 증가 정밀도 명확하지 않다 다음 회의에 대한
(.round 3.14159M (java.math.MathContext. 7)) ; 3.14159M (unexpected)
,이 하지입니다 후미 0이 표시되지 않습니다.
(.precision (.round 3.14159M (java.math.MathContext. 7))) ; 6
; (same as above, still unexpected)
FWIW는 Clojure의는 후행 0에주의하고 는 그들을 표시합니다 :
궤도에4.0000M ; 4.0000M
(.precision 4.0000M) ; 5
... 당신은 BigDecimal 생성자를 사용하여 시도 할 수 있지만,보다 높은 정밀도를 설정하지 않습니다 지정한 자릿수 :
(BigDecimal. "3" (java.math.MathContext. 5)) ; 3M
(BigDecimal. "3.1" (java.math.MathContext. 5)) ; 3.1M
따라서 정확도를 빠르게 변경할 수는 없습니다. 나는이 질문을 쓰는 동안 그리고 내가 일하고있는 프로젝트와 함께 이것을 싸우는 데 시간을 보냈다. 나는 이것을 기껏해야 CRAZYTOWN API와 최악의 버그라고 생각한다. 사람들. 진심으로?당신은 정밀도를 변경하려는 경우
그래서, 최고의 내가 다음 단계를 수행해야합니다, 말할 수 :
- 조회 현재 정밀도를.
- 현재 눈금을 찾습니다.
- 스케일 변경을 계산하십시오.
- 는 Clojure의 코드로, 새로운 규모
이 단계를 설정합니다
내가 아는(def x 0.000691M) ; the input number
(def p' 1) ; desired precision
(def s' (+ (.scale x) p' (- (.precision x)))) ; desired new scale
(.setScale x s' BigDecimal/ROUND_HALF_EVEN)
; 0.0007M
, 이것은 단지 정밀도를 변경하려면 많은 단계입니다!
왜 BigDecimal은 이미 이것을 제공하지 않습니까? 내가 간과 했니?
'BigDecimal.round (새로운 MathContext (정밀도, RoundingModel.ROUND_HALF_EVEN))'은 어떨까요? –
@ PaŭloEbermann 당신은 묻고 있습니까? 너 해봤 어? 내 대답을 통해 실행 한 사례에 대한 자세한 결과 공유 그렇다면 별도의 답변이 필요하다고 생각합니다. –
나 같은 사람이고 Clojure에 대해 조금도 알지 못한다면, 여기에있는 해결책은'x.setScale (x.scale() + p - x.precision(), RoundingMode.HALF_UP)'' x'는 반올림하려는 'BigDecimal'이고,'p'는 유지하고자하는 유효 숫자의 수입니다. 그것은 나를 위해 일하고 있지만 내가 틀렸다면 나에게 정정하십시오! – Nateowami
BigDecimal decPrec = (BigDecimal)yo.get("Avg");
decPrec = decPrec.setScale(5, RoundingMode.CEILING);
String value= String.valueOf(decPrec);
이렇게하면 BigDecimal
의 특정 정밀도를 설정할 수 있습니다.
로 반올림 했다 ...
Integer perc = 5;
BigDecimal spread = BigDecimal.ZERO;
BigDecimal perc = spread.setScale(perc,BigDecimal.ROUND_HALF_UP);
System.out.println(perc);
결과 : 0.00000
당신이 생성자 MathContext를주는 시도? – bdares
올바르게 보았다면 부동 소수점 정밀도가 아니라 소수점 자리를 말하는 것입니다. 적어도 받아 들여지는 대답은 정밀도 12 자리가 아닌 소수 12 자리가됩니다. – vbence