接下来的两行在相同的日期添加相同的金额,结果日期部分是相同的,但不知何故,时间部分有差异!
(new DateTime(2000,1,3,18,0,0)).AddDays(4535);
(new DateTime(2000,1,3,18,0,0)).AddMonths(149);
Run Code Online (Sandbox Code Playgroud)
你会得到15秒的差异,并且两者至少可以倒圆几天,我不知道为什么会发生这种情况,但它只发生在AddDays,而不是AddMonths(即使添加了数千个月)
编辑1
所以我试图制作一个示例项目,但没有运气.如果我运行我的主项目,并将样品线放入手表,而不是我得到2个单独的值,如果我重新开始,问题就不存在了.该项目是3.5,c#,vs2010,win7hp x64(proj:x86).我正在尝试在一个新的小项目中重现它,如果我有它,我会写回来.
这些是我在主要项目中的结果(来自手表的copeid!):
(new DateTime(2000, 1, 3, 18, 0, 0)).AddDays(4535).Ticks
634743432153600000 long
(new DateTime(2000, 1, 3, 18, 0, 0)).AddMonths(149).Ticks
634743432000000000 long
Run Code Online (Sandbox Code Playgroud)
编辑2
我已经设法将它缩小了.我们有一个自制组件,面板底座,我们使用directx绘制它.如果我在visible = true(或show())之前使那个visible = false,而不是visible = true,那么计算是正确的.世界上可以有什么,结果得到了一个没有使用变量的公式.文化不受组件影响..
这是DirectX默默地将CPU的浮点计算模式更改为始终使用单精度的结果。有时这样做是为了提高性能:使用单精度可能比使用双精度快很多。FpuPreserve请参阅DirectX 枚举的 MSDN 文档中对该标志的描述CreateFlags。
其他人无法重现此问题的原因是他们没有执行这些 DirectX 调用。
的参数AddDays是 a double。该值乘以比例因子即可得到以毫秒为单位的时间。正是这种计算产生了误差。
考虑:
double value = 4535;
int scale = 86400000;
long milliseconds = (long) ((value * scale) + ((value >= 0.0) ? 0.5 : -0.5));
long milliseconds2 = (long)((float)(value * scale) + ((value >= 0.0) ? 0.5 : -0.5));
Console.WriteLine(milliseconds2 - milliseconds);
Run Code Online (Sandbox Code Playgroud)
的表达式milliseconds2包含对 的强制转换float,它模仿 DirectX 强制单精度计算的效果。这将打印出15360您发现的差异。
相比之下,AddMonths采用整数,并且不使用任何浮点运算。所以结果是准确的。