我正在处理物理实体,例如时间、速度和距离,并执行简单的数学运算,例如距离 = 时间 * 速度等。速度和距离是四舍五入到第 8 位的双精度值,对于时间值是 .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; }
谢谢,鲍里斯。