2010-07-26 4 views
2

시간, 속도 및 거리와 같은 실제 엔터티를 처리하고 거리 = 시간 * 속도 등과 같은 간단한 계산을 수행합니다. 속도 및 거리는 8 번째 숫자로 반올림 된 이중 값이며, Time 값의 경우 .NET TimeSpan이 사용됩니다. TimeSpan은 가장 가까운 밀리 초로 반올림하므로 반올림 오류가 발생하므로 모든 계산을 가장 가까운 밀리 초로 반올림하는 사용자 지정 반올림 방법을 작성해야합니다. (예를 들어 8 자리로 반올림 생략한다)TimeSpan 및 이중 반올림 오류

static void Main(string[] args) { 
    var dist = 1.123451; 
    var speed = 1.123452; 

    var timeA = TimeSpan.FromHours(dist/speed); 
    var timeB = timeA + TimeSpan.FromMilliseconds(1); 

    var distA = _round(timeA.TotalHours * speed); 
    var distB = _round(timeB.TotalHours * speed); 

    var timeA1 = TimeSpan.FromHours(distA/speed); 
    var timeB1 = TimeSpan.FromHours(distB/speed); 

    // a correct implementation should give both the following vars true 
    var isDistributive = distA == dist; 
    var isPrecise = (timeB1 - timeA1) == TimeSpan.FromMilliseconds(1); 
    } 

    public static double _round(double d) { 
    // Q: what should be here? 
    } 
  • 는 Math.Round 사용의 (d, 6)에 분배이지만, 수학을 사용
  • (~ 4 밀리 초까지 정확하게) 정밀도를 잃게 .Round (d, 7)는 하나의 msec에 정확하지만 분배가 불가능합니다 (위의 distA는 1.1234511! = 1.123451입니다)
  • 다음을 사용하면 (가장 가까운 가장 가까운 반올림) 올바른 것으로 보이지만 반올림 코드 자체 자체 배정도 오류가 발생합니다.

    public static double _round(double d) { 
        var pre = 3600000.0; 
        return Math.Round(d * pre)/pre; 
        } 
    

감사합니다. Boris.

답변

2

Jon Skeet도 .Net 시간 계산에 만족하지 않으며이 문제를 해결할 수 있다고 생각하는 noda-time 프로젝트에서 작업하고 있습니다. 프로젝트가 너에게 익숙 할만큼 충분히 멀리 있는지는 모르지만 확인해 볼 가치가있다.

편집 : 사람들이 휠을 재발행하기보다는 불필요하게 라이브러리를 사용하고 개선하도록하기 위해 뻔뻔스럽게도 JS 이름을 사용합니다.

0

double 유형 대신 십진수를 사용해보십시오. 더 정확한 (28 자리 정밀도) 맞춤 라운드 기능을 구현하지 않아도 사용자의 요구에 맞아야합니다.

+0

내 문제는 이중 정밀도를 잃지 않고 있습니다. 내 문제는 TimeSpan에서 정밀도를 잃어 가고 있습니다 .FromHours – Borka