假设您是负责设计TimeSpan
类型的开发人员。您已经具备了所有基本功能;这一切似乎都很好。然后有一天,某个 Beta 测试人员出现并向您展示了以下代码:
double x = 100000000000000;
double y = 0.5;
TimeSpan t1 = TimeSpan.FromMilliseconds(x + y);
TimeSpan t2 = TimeSpan.FromMilliseconds(x) + TimeSpan.FromMilliseconds(y);
Console.WriteLine(t1 == t2);
为什么会输出False
?测试人员问你。即使您理解为什么会发生这种情况(将x
和加在一起时精度损失),您也必须承认,从客户的角度来看,y
这确实有点奇怪。然后他把这个扔给你:
x = 10.0;
y = 0.5;
t1 = TimeSpan.FromMilliseconds(x + y);
t2 = TimeSpan.FromMilliseconds(x) + TimeSpan.FromMilliseconds(y);
Console.WriteLine(t1 == t2);
那个输出True
!测试人员的怀疑是可以理解的。
此时,您需要做出决定。您可以允许TimeSpan
在从值构造的值之间进行算术运算double
以产生精度超过double
类型本身精度的结果——例如,100000000000000.5(16 个有效数字)——或者你可以,你知道,不允许这样做。
所以你决定,你知道吗,我会这样做,以便任何使用 adouble
构造 a 的方法TimeSpan
都将四舍五入到最接近的毫秒。这样,明确记录了从 a 转换double
为 a是一个有损操作,如果客户在从toTimeSpan
转换后看到这样的奇怪行为并希望得到准确的结果,则可以免除我的责任。double
TimeSpan
我不一定认为这是“正确”的决定。显然,这种方法本身会引起一些混乱。我只是说需要以一种或另一种方式做出决定,而这显然是决定的。