2016-06-10 1 views
0

나는 다양한 소수 자릿수의 두 배로 된 그룹을 가지고 있습니다. 그 값의 SUM()을 가져온 다음 SUM()을 1로 만들기 위해 모든 값을 정규화해야합니다. 또한 최종 결과에서 소수점 이하 자릿수를 4로 제한해야한다는 요구 사항이 있습니다.이를 수행하려면 나는 다음과 같은 일을 시도 :Double을 사용하는 정규화

normalizationFactor = 1/sumOfAllDoublesInGroup; 

for(Object myObject : myGroupOfObjects){ 
    myObject.setDoubleValue = round(myObject.getDoubleValue * normalizationFactor),4); 
} 

private Double round (Double doubleValue, Integer decimalPlaces) { 
    if (places < 0) throw new IllegalArgumentException(); 

    BigDecimal bd = new BigDecimal(value); 
    bd = bd.setScale(places, RoundingMode.HALF_UP); 
    return bd.doubleValue(); 
} 

여기에서의 단점 찰나 나는 아직도 모든 복식의 SUM()가 여전히 == 1. 나는 그와 약간의 도움을 주셔서 감사합니다 것입니다 보장 할 수 있다는 것입니다.

유일한 요구 사항은

1) 나는 숫자의 집합 소수점 이하 자릿수의 각각은 다양한 수를 얻을 수 있습니다 분명합니다. 2) 모두 말한 후 각 숫자는 소수점 이하 4 자리로 제한됩니다. 3) 그룹의 모든 숫자의 최종 SUM()은 반드시 1이어야합니다.

+0

'places' 대신'decimalPlaces'를 사용 했습니까? 숫자 세트를 두 번 통과해야합니다. 또는 합계를 1로 만들기 위해 하나의 숫자에서 0.0001을 더하거나 빼야합니다. –

+0

정확히 1이 필요하면 하나의 숫자를 1을 빼고 다른 숫자의 합을 빼낼 수 있습니다. 그러나 정확한 십진수의 정확도는 일반적인 경우에는 '이중'의 이진 특성으로 인해 충족되지 않습니다 –

답변

0

코드에 double과 BigDecimal 사이에 많은 변환이 있습니다. 이러한 변환은 값에 배정도 오류를 추가하는 것일 수 있습니다. 아래의 코드를 찾으십시오. 모든 숫자는 BigDecimal에 저장됩니다.

List<BigDecimal> myGroupOfObjects = new ArrayList<>(); 
    myGroupOfObjects.add(new BigDecimal("0.3")); 
    myGroupOfObjects.add(new BigDecimal("0.1")); 
    myGroupOfObjects.add(new BigDecimal("0.2")); 
    myGroupOfObjects.add(new BigDecimal("0.2")); 

    BigDecimal sumOfAllDoublesInGroup = new BigDecimal("0.8"); // #HardCoding 

    BigDecimal normalizationFactor = new BigDecimal("1.0") 
     .divide(sumOfAllDoublesInGroup); 

    BigDecimal result = new BigDecimal(0); 
    for(BigDecimal myObject : myGroupOfObjects){ 
     myObject = myObject.multiply(normalizationFactor) 
       .setScale(4, RoundingMode.HALF_UP); 

     result = result.add(myObject); 
    } 

Result: 
0.3750 
0.1250 
0.2500 
0.2500 
------ 
1.0