我查看了DateTime Equals实现:
public bool Equals(DateTime value)
{
return (this.InternalTicks == value.InternalTicks);
}
然后查看internalticks
internal long InternalTicks
{
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
get
{
return (((long) this.dateData) & 0x3fffffffffffffffL);
}
}
然后我注意到这个号码:0x3fffffffffffffffL
是:4611686018427387903
但更多有趣的是它的二进制表示:
00111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
^^
||
请注意箭头
我可以理解,只有左侧箭头是0
(正面呈现)
但为什么第二个也是0
?
另外,为什么我每个人都希望&
号码为1111....
?如果我想显示5
我不需要5 & 1
,只需要5。
任何帮助?
答案 0 :(得分:7)
您可以从Reference Source获取此类信息。 dd / ndp / clr / src / bcl / system / datetime.cs中最相关的声明:
private const UInt64 TicksMask = 0x3FFFFFFFFFFFFFFF;
private const UInt64 FlagsMask = 0xC000000000000000;
private const UInt64 LocalMask = 0x8000000000000000;
private const Int64 TicksCeiling = 0x4000000000000000;
private const UInt64 KindUnspecified = 0x0000000000000000;
private const UInt64 KindUtc = 0x4000000000000000;
private const UInt64 KindLocal = 0x8000000000000000;
private const UInt64 KindLocalAmbiguousDst = 0xC000000000000000;
private const Int32 KindShift = 62;
注意 Kind 值如何映射到这两位。
public DateTime(long ticks, DateTimeKind kind) {
// Error checking omitted
//...
this.dateData = ((UInt64)ticks | ((UInt64)kind << KindShift));
}
答案 1 :(得分:4)
dateData
字段与bit field类似,用于以紧凑格式存储多个值。
前两位存储DateTimeKind,其中包含四个可能的值之一:Unspecified,Local(内部有两个变体)或Utc。这四个值可以存储为两位。
底部62位存储刻度线。操作x & 0x3fffffffffffffffL
是按位和操作,有时也称为masking。它只返回与刻度相对应的位。