.NET AddDays问题

use*_*009 12 .net c# datetime

接下来的两行在相同的日期添加相同的金额,结果日期部分是相同的,但不知何故,时间部分有差异!

(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,那么计算是正确的.世界上可以有什么,结果得到了一个没有使用变量的公式.文化不受组件影响..

Jef*_*Sax 3

这是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采用整数,并且不使用任何浮点运算。所以结果是准确的。