接下来的两行在相同的日期添加相同的金额,结果日期部分是相同的,但不知何故,时间部分有差异!
(new DateTime(2000,1,3,18,0,0)).AddDays(4535);
(new DateTime(2000,1,3,18,0,0)).AddMonths(149);
你会得到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
修改2
我已经设法将其缩小范围了。我们有一个自制组件,面板底座,我们使用directx绘制它。如果我在visible = true(或show())之前使那个visible = false,而不是visible = true,那么计算是正确的。世界上可以有什么,结果得到了一个没有使用变量的公式。文化不受组成部分的影响..
答案 0 :(得分:4)
这里他们给出了相同的结果:
var d1 = (new DateTime(2000, 1, 3, 18, 0, 0)).AddDays(4535).Ticks;
var d2 = (new DateTime(2000, 1, 3, 18, 0, 0)).AddMonths(149).Ticks;
d1 == d2 == 634743432000000000
(Tick是DateTime时间的内部“量子”。它很短。它是one ten-millionth of a second
我要补充一点,即使是Mono(.NET的独立实现)也会得到相同的结果http://ideone.com/krySY(Ideone使用单声道)
考虑到你写的最近的事情,这很容易:内存损坏。内存损坏可以做很随机的事情。这可能是其中之一: - )
答案 1 :(得分:3)
这是DirectX静默更改CPU的浮点计算模式以始终使用单精度的结果。这有时是为了提高性能:使用单精度可以比使用双精度快一点。有关DirectX CreateFlags
枚举的信息,请参阅MSDN文档中FpuPreserve
标志的说明。
其他人无法重现这一点的原因是因为他们没有进行那些DirectX调用。
AddDays
的参数是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);
milliseconds2
的表达式包含对float
的强制转换,它模仿DirectX强制进行单精度计算的效果。这将打印15360
,确切地说是您找到的差异。
相比之下,AddMonths
采用整数,并且不使用任何浮点运算。所以结果是准确的。