Java에서 부동 소수점 산술과 그 정밀도에 관한 질문이 있습니다. 나는 여기와 구글을 통해 내 연구를 수행했지만 몇 가지 해결책을 찾아 왔지만 디자인에 어려움을 겪고있다. 그래서 자바에서는 정확한 계산을하기 위해 BigDecimal 클래스를 사용하고 있습니다. 변수는 double이고 값은 계산할 때 오른쪽으로 소수점 이하 8 자까지의 정확도를 가질 수 있습니다. 표시 할 결과 (정밀도)는 알려져 있으며 현재 값으로 저장할 것입니다. 또한 모든 값은 동적으로 (메소드를 통해) 들어옵니다. 전달 된 인수는 currentValue + 단계 크기 여야합니다.Java 부동 소수점 정밀도
public void newValue(float value) {
//Clip to valid range, can't go over minimum/max value
value = Math.max(minimumValue, Math.min(maximumValue, value));
// TODO Implement better Floating Point Arithmetic precision
MathContext mcI = new MathContext(0, RoundingMode.HALF_UP);
MathContext mcF = new MathContext(8, RoundingMode.HALF_UP);
BigDecimal valueBD = new BigDecimal(value, mcF);
BigDecimal minimumBD = new BigDecimal(minimumValue, mcF);
BigDecimal stepBD = new BigDecimal(step, mcF);
BigDecimal currentValueBD = new BigDecimal(currentValue, mcF);
BigDecimal totalStepsBD = valueBD.subtract(minimumBD, mcF);
//Ensure value is divisible by stepsize
totalStepsBD = totalStepsBD.divide(stepBD, mcI);
valueBD = stepBD.multiply(totalStepsBD, mcF);
valueBD = valueBD.add(minimumBD, mcF);
// arithmetic without using BigDecimal (old)
//int totalSteps = (int) ((value- minimumValue)/ step);
//value = totalSteps * step + minimumValue;
if(!(valueBD.equals(currentValueBD))) {
valueBD = valueBD.setScale(displayPrecision, RoundingMode.HALF_UP);
currentValue = valueBD.floatValue();
dispatch();
}
}
지금, 일부 값 전부는 아니지만 작동합니다. 특히 스텝 사이즈가 엉망이라면. 그래서 step = 0.1이라면 괜찮 았을 것입니다. 나는 그것을 0.005 한 경우, 나는 AirthmeticException를 얻을 것 - 비 종단 진수 확장을
totalStepsBD = totalStepsBD.divide(stepBD, mcI);
이 0.005가 BigDeciaml (stepBD)를 한 후, 스텝 변수에 설정되어있는 단계가 나옵니다에. 0049999999 ... 그게 도움이 될지 모르지만 아이디어가 있다면 알려주세요. 고맙습니다.
난 당신이 정의하는가 '어디 step' 볼 수 없습니다 사용, 그래서 있으리라 믿고있어이에 멤버 변수입니다 클래스. 'float'유형이고 0.005로 지정되면 .0049999999 또는 유사한 것으로 저장됩니다. 그런 다음'stepBD'에'step'의 값을 지정하면 0.005가 아닌 0.00499 값을 사용합니다. 이것이 문제인지 확실하지 않지만 도움이 될 수 있습니다. – Grice
주 :'.equals()'를 사용하여'BigDecimal'을 비교하지 마십시오; 예를 들어 '0'과 '0.00'은 동일하지 않습니다. '.compareTo()'를 사용하고 대신'== 0'을 체크하십시오. – fge