9

2 つのオブジェクト間のミリ秒の差を計算するとDateTime、数値の小数部分が数値の整数部分と同じである数値が常に返されるようです。例えば:1235.1235

なぜこれが起こるのですか?私は何か間違ったことをしていますか?DateTimeこれは言語の癖ですか、それとも粒度の制限ですか?

これは、次のコードを使用して実証できます。

        DateTime then = DateTime.Now;
        Thread.Sleep(1234);
        DateTime now = DateTime.Now;
        TimeSpan taken = now - then;
        string result = taken.TotalMilliseconds.ToString(CultureInfo.InvariantCulture);
        //result = "1235.1235"

CodesInChaos のコメント:

DateTime` は、このレベルの精度では正確ではありません: C# DateTime.Now の精度を参照してください。

ただし、それではこの動作を完全には説明できません。

4

1 に答える 1

4

これには技術的な説明があります。そうでなければ、それがあなたの観察を説明していると証明することはできません。私のマシンでは確かに再現しません。

ノイズ桁を探している初心者にとって、オペレーティングシステムのクロックは、ミリ秒未満の精度を提供するのに十分なほど正確ではありません。したがって、重要なことを行うために、その値に依存しないようにしてください。高解像度で間隔を測定したい場合は、代わりにストップウォッチを使用する必要があります。

オペレーティング システムのクロックは、タイム サーバーからの更新の影響を受けます。ほとんどのマシンは、定期的に連絡time.windows.comしてクロックを再調整するように設定されています。これにより、クロックのずれが解消されます。通常、マシンのハードウェアは、1 か月にわたって 1 秒未満の正確な時間を維持するには十分ではありません。公差の小さい水晶は高価であり、温度や経年変化によるドリフトが完全になくなるわけではありません。また、地球のゆっくりとした自転に合わせてクロックを同期させるために、うるう秒が時々挿入されます。最後の 1 つは、多くの Linux マシンをクラッシュさせました。「Linux うるう秒のバグ」を検索して、楽しく読んでください。

ここで重要なのは、マシンがクロックの調整を必要とする新しい更新を取得したときに何が起こるかです。Windows は、クロック値に突然ジャンプすることはありませ。これは、クロックに注意を払い、予測可能な量で一貫して増加することを期待しているプログラムに大きな問題を引き起こします。

代わりに、クロックティックの増分ごとに少しずつ追加します。実際には、クロックを少し遅くしたり速くしたりして、徐々に差を埋めて再び正確になるようにします. 余分に追加されたマイクロ秒は、間隔の長さに比例します。したがって、ノイズ桁で間隔が繰り返されるのを見るのはもっともらしいです。

この理論を証明する唯一の現実的な方法は、GetSystemTimeAdjustment() を呼び出すことです。システム時刻の調整が進行中の場合は、0 以外の値が返されます。次に、 SetSystemTimeAdjustment() をピンボークして無効にし、表示される値に違いが生じるかどうかを観察します。または、時計が追いつくまで十分に待って、それ以上調整されないようにします.

于 2013-02-28T19:10:47.277 に答える