Я имею дело с физическими объектами, такими как время, скорость и расстояние, и выполняю простую математику, такую как расстояние = время * скорость и т. Д. Скорость и расстояние - это двойные значения, округленные до 8-й цифры, а для значений времени a.NET TimeSpan используется.Поскольку TimeSpan округляется до ближайшей миллисекунды, я получаю ошибки округления, поэтому мне нужно написать собственный метод округления, который округляет все вычисления до ближайшей миллисекунды.Например (округление до 8-й цифры для простоты опущено):
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 мс)
- Использование Math.Round (d, 7) с точностью до одного мс, но не дистрибутивное (distA выше будет 1.1234511! = 1.123451)
Использование следующего (округление до ближайшего мс) кажется правильным, но сам код округления вводит свои собственные ошибки двойной точности:
public static double _round(double d) {
var pre = 3600000.0;
return Math.Round(d * pre) / pre;
}
Спасибо, Борис.