Hello,
I'm dealing with physical entities, such as time, speed and distance, and performing simple math, such as distance = time * speed, etc. Speed and Distance are double values rounded to 8th digit, and for Time values a .NET TimeSpan is used. Since TimeSpan rounds to a closest millisecond, I'm getting rounding errors, so I need to write custom rounding method that rounds all calculations to the closest millisecond. For example (rounding to 8th digit is omitted for simplicity):
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?
}
- Using Math.Round(d, 6) is distributive, but loses precision (precise up to ~4 msec)
- Using Math.Round(d, 7) is precise to a single msec, but not distributive (distA above will be 1.1234511 != 1.123451)
Using the following (round to closest msec) seems to be correct, but the rounding code itself introduces its own double precision errors:
public static double _round(double d) { var pre = 3600000.0; return Math.Round(d * pre) / pre; }
Thanks, Boris.